Documentation
¶
Overview ¶
Package patchapply applies parsed patches to files.
It is the apply half of go-mailpatch: mailpatch turns a format-patch email into structured FileChanges; patchapply takes those (or a bare unified diff) and writes the changes to a filesystem — creating, modifying, deleting, renaming, and copying files. It can also reverse a patch and dry-run one without writing.
Apply runs against an FS, not directly against the OS. Use DirFS to confine every path to a directory (patches that try to escape via "../" fail with ErrUnsafePath), or MemFS to apply entirely in memory.
Application is transactional: every file is read and every hunk is placed in memory first, so if any hunk fails to apply (ErrConflict) nothing is written.
It never executes git.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrConflict is returned (wrapped, with the file and hunk) when a hunk's // context cannot be matched in the target file. ErrConflict = errors.New("patchapply: hunk does not apply") // ErrUnsafePath is returned by DirFS when a patch path escapes the root. ErrUnsafePath = errors.New("patchapply: unsafe path") // ErrExists is returned when a patch adds a file that is already present. ErrExists = errors.New("patchapply: file already exists") // ErrMissing is returned when a patch modifies, deletes, or renames a file // that is not present. ErrMissing = errors.New("patchapply: target file not found") )
Sentinel errors. Compare with errors.Is.
Functions ¶
func ApplyToBytes ¶
func ApplyToBytes(orig []byte, f mailpatch.FileChange) ([]byte, error)
ApplyToBytes applies a single file's hunks to orig and returns the new contents. It is the pure, filesystem-free core: read a file yourself, pass its bytes here, write the result yourself.
Hunks are located at the line numbers the diff records, but a whole-hunk offset is tolerated (so a patch still applies when earlier, unrelated edits shifted the file). Context lines must match exactly — there is no fuzz. A hunk that cannot be placed returns an error wrapping ErrConflict.
Types ¶
type DirFS ¶
type DirFS struct {
// contains filtered or unexported fields
}
DirFS is an FS rooted at a directory on the real filesystem. Every path is confined to the root: a patch whose path escapes it (via "../" or an absolute path) fails with ErrUnsafePath instead of touching anything outside.
type FS ¶
type FS interface {
// ReadFile returns the current contents of name. It must report a
// not-exist error (testable with os.IsNotExist / fs.ErrNotExist) when the
// file is absent.
ReadFile(name string) ([]byte, error)
// WriteFile creates or overwrites name with data, creating parent
// directories as needed.
WriteFile(name string, data []byte, perm fs.FileMode) error
// Remove deletes name.
Remove(name string) error
// Exists reports whether name currently exists.
Exists(name string) bool
}
FS is the filesystem an apply runs against: read the current files, write new content, and remove deletions. DirFS (rooted at a directory) and MemFS (in memory) implement it. Implement it yourself to apply patches against, say, a git object store or a virtual tree.
type FileResult ¶
type FileResult struct {
Path string // resulting path; for a removal, the path removed
OldPath string // previous path for a rename, else empty
Status Status
Hunks int // hunks applied
}
FileResult records what an apply did (or, for a dry run, would do) to one file.
type MemFS ¶
type MemFS struct {
// contains filtered or unexported fields
}
MemFS is an in-memory FS, handy for tests and for applying a patch to a set of files you already hold in memory. The zero value is not usable; use NewMemFS.
func NewMemFS ¶
NewMemFS returns an empty MemFS. Seed it with WriteFile or by passing initial files.
type Options ¶
type Options struct {
// Reverse undoes the patch instead of applying it.
Reverse bool
// DryRun validates the whole patch (reads and places every hunk) but
// writes nothing. A nil error means a real apply would succeed.
DryRun bool
}
Options tunes an apply.
type Result ¶
type Result struct {
Files []FileResult
}
Result is the outcome of an apply.