control

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2023 License: BSD-3-Clause, MIT Imports: 24 Imported by: 47

Documentation

Overview

Parse the Debian control file format.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(writer io.Writer, data interface{}) error

Marshal is a one-off interface to serialize a single object to a writer.

Most notably, this will *not* separate Paragraphs with a newline as is expected upon repeated calls, please use the Encoder streaming interface for that.

It's also worth noting that this *will* also write out elements that were Unmarshaled into a Struct without a member of that name if (and only if) the target Struct contains a `control.Paragraph` anonymous member.

This is handy if the Unmarshaler was given any `X-*` keys that were not present on your Struct.

Given a struct (or list of structs), write to the io.Writer stream in the RFC822-alike Debian control-file format

This code will attempt to unpack it into the struct based on the literal name of the key, This can be overridden by the struct tag `control:""`.

If you're dehydrating a list of strings, you have the option of defining a string to join the tokens with (`delim:", "`).

In order to Marshal a custom Struct, you are required to implement the Marshallable interface. It's highly encouraged to put this interface on the struct without a pointer receiver, so that pass-by-value works when you call Marshal.

func Unmarshal

func Unmarshal(data interface{}, reader io.Reader) error

Given a struct (or list of structs), read the io.Reader RFC822-alike Debian control-file stream into the struct, unpacking keys into the struct as needed. If a list of structs is given, unpack all RFC822 Paragraphs into the structs.

This code will attempt to unpack it into the struct based on the literal name of the key, compared byte-for-byte. If this is not OK, the struct tag `control:""` can be used to define the key to use in the RFC822 stream.

If you're unpacking into a list of strings, you have the option of defining a string to split tokens on (`delim:", "`), and things to strip off each element (`strip:"\n\r\t "`).

If you're unpacking into a struct, the struct will be walked according to the rules above. If you wish to override how this writes to the nested struct, objects that implement the Unmarshallable interface will be Unmarshaled via that method call only.

Structs that contain Paragraph as an Anonymous member will have that member populated with the parsed RFC822 block, to allow access to the .Values and .Order members.

func UnpackFromParagraph

func UnpackFromParagraph(para Paragraph, incoming interface{}) error

Unpack a Paragraph into a Struct, as if that data had been unpacked into that struct to begin with. The normal rules from running the Unmarshal API directly apply when unpacking a Paragraph using UnpackFromParagraph.

In most cases, the Unmarshal API should be sufficient. Use of this API is mildly discouraged.

Types

type BestChecksums

type BestChecksums struct {
	ChecksumsSha256 []SHA256FileHash `control:"Checksums-Sha256" delim:"\n" strip:"\n\r\t "`
	ChecksumsSha512 []SHA256FileHash `control:"Checksums-Sha512" delim:"\n" strip:"\n\r\t "`
}

BestChecksums can be included in a struct instead of e.g. ChecksumsSha256.

BestChecksums uses cryptographically secure checksums, so that application code does not need to worry about that.

The struct fields of BestChecksums need to be exported for the unmarshaling process but most not be used directly. Use the Checksums() accessor instead.

func (*BestChecksums) Checksums

func (b *BestChecksums) Checksums() []FileHash

Checksums returns FileHashes of a cryptographically secure kind.

type BinaryIndex

type BinaryIndex struct {
	Paragraph

	Package        string
	Source         string
	Version        version.Version
	InstalledSize  int `control:"Installed-Size"`
	Maintainer     string
	Architecture   dependency.Arch
	MultiArch      string `control:"Multi-Arch"`
	Description    string
	Homepage       string
	DescriptionMD5 string   `control:"Description-md5"`
	Tags           []string `delim:", "`
	Section        string
	Priority       string
	Filename       string
	Size           int
	MD5sum         string
	SHA1           string
	SHA256         string

	DebugBuildIds []string `control:"Build-Ids" delim:" "`
}

The BinaryIndex struct represents the exported APT Binary package index file, as seen on Debian (and Debian derived) mirrors, as well as the cached version in /var/lib/apt/lists/.

This can be used to examine Binary packages contained in the Archive, to examine things like Built-Using, Depends, Tags or Binary packages present on an Architecture.

func ParseBinaryIndex

func ParseBinaryIndex(reader *bufio.Reader) (ret []BinaryIndex, err error)

Given a reader, parse out a list of BinaryIndex structs.

func (*BinaryIndex) GetBreaks

func (index *BinaryIndex) GetBreaks() dependency.Dependency

Parse the Depends Breaks relation on this package.

func (*BinaryIndex) GetBuiltUsing

func (index *BinaryIndex) GetBuiltUsing() dependency.Dependency

Parse the Built-Depends relation on this package.

func (*BinaryIndex) GetConflicts added in v0.13.0

func (index *BinaryIndex) GetConflicts() dependency.Dependency

Parse the Conflicts Dependency relation on this package.

func (*BinaryIndex) GetDepends

func (index *BinaryIndex) GetDepends() dependency.Dependency

Parse the Depends Dependency relation on this package.

func (*BinaryIndex) GetPreDepends

func (index *BinaryIndex) GetPreDepends() dependency.Dependency

Parse the Depends Pre-Depends relation on this package.

func (*BinaryIndex) GetReplaces

func (index *BinaryIndex) GetReplaces() dependency.Dependency

Parse the Depends Replaces relation on this package.

func (*BinaryIndex) GetSuggests

func (index *BinaryIndex) GetSuggests() dependency.Dependency

Parse the Depends Suggests relation on this package.

func (*BinaryIndex) SourcePackage

func (index *BinaryIndex) SourcePackage() string

SourcePackage returns the Debian source package name from which this binary Package was built, coping with the special cases Source == Package (skipped for efficiency) and binNMUs (Source contains version number).

type BinaryParagraph

type BinaryParagraph struct {
	Paragraph
	Architectures []dependency.Arch `control:"Architecture"`
	Package       string
	Priority      string
	Section       string
	Essential     bool
	Description   string
	Conffiles     []MD5FileHash `delim:"\n" strip:"\n\r\t "`

	Depends    dependency.Dependency
	Recommends dependency.Dependency
	Suggests   dependency.Dependency
	Enhances   dependency.Dependency
	PreDepends dependency.Dependency `control:"Pre-Depends"`

	Breaks    dependency.Dependency
	Conflicts dependency.Dependency
	Replaces  dependency.Dependency

	BuiltUsing dependency.Dependency `control:"Built-Using"`
}

Encapsulation for a debian/control Binary control entry. This contains information that will be eventually put lovingly into the .deb file after it's built on a given Arch.

type Changes

type Changes struct {
	Paragraph

	Filename string

	Format          string
	Source          string
	Binaries        []string          `control:"Binary" delim:" "`
	Architectures   []dependency.Arch `control:"Architecture"`
	Version         version.Version
	Origin          string
	Distribution    string
	Urgency         string
	Maintainer      string
	ChangedBy       string `control:"Changed-By"`
	Closes          []string
	Changes         string
	ChecksumsSha1   []SHA1FileHash            `control:"Checksums-Sha1" delim:"\n" strip:"\n\r\t "`
	ChecksumsSha256 []SHA256FileHash          `control:"Checksums-Sha256" delim:"\n" strip:"\n\r\t "`
	Files           []FileListChangesFileHash `control:"Files" delim:"\n" strip:"\n\r\t "`
}

The Changes struct is the default encapsulation of the Debian .changes package filetype.This struct contains an anonymous member of type Paragraph, allowing you to use the standard .Values and .Order of the Paragraph type.

The .changes files are used by the Debian archive maintenance software to process updates to packages. They consist of a single paragraph, possibly surrounded by a PGP signature. That paragraph contains information from the debian/control file and other data about the source package gathered via debian/changelog and debian/rules.

func ParseChanges

func ParseChanges(reader *bufio.Reader, path string) (*Changes, error)

Given a bufio.Reader, consume the Reader, and return a Changes object for use. The "path" argument is used to set Changes.Filename, which is used by Changes.GetDSC, Changes.Remove, Changes.Move and Changes.Copy to figure out where all the files on the filesystem are. This value can be set to something invalid if you're not using those functions.

func ParseChangesFile

func ParseChangesFile(path string) (ret *Changes, err error)

Given a path on the filesystem, Parse the file off the disk and return a pointer to a brand new Changes struct, unless error is set to a value other than nil.

func (*Changes) AbsFiles

func (changes *Changes) AbsFiles() []FileListChangesFileHash

Return a list of FileListChangesFileHash entries from the `changes.Files` entry, with the exception that each `Filename` will be joined to the root directory of the Changes file.

func (*Changes) Copy

func (changes *Changes) Copy(dest string) error

Copy the .changes file and all referenced files to the directory listed by the dest argument. This function will error out if the dest argument is not a directory, or if there is an IO operation in transfer.

This function will always move .changes last, making it suitable to be used to move something into an incoming directory with an inotify hook. This will also mutate Changes.Filename to match the new location.

func (*Changes) GetDSC

func (changes *Changes) GetDSC() (*DSC, error)

Return a DSC struct for the DSC listed in the .changes file. This requires Changes.Filename to be correctly set, and for the .dsc file to exist in the correct place next to the .changes.

This function may also return an error if the given .changes does not include the .dsc (binary-only upload)

func (*Changes) Move

func (changes *Changes) Move(dest string) error

Move the .changes file and all referenced files to the directory listed by the dest argument. This function will error out if the dest argument is not a directory, or if there is an IO operation in transfer.

This function will always move .changes last, making it suitable to be used to move something into an incoming directory with an inotify hook. This will also mutate Changes.Filename to match the new location.

func (*Changes) Remove

func (changes *Changes) Remove() error

Remove the .changes file and any associated files. This function will always remove the .changes last, in the event there are filesystem i/o errors on removing associated files.

type Control

type Control struct {
	Filename string

	Source   SourceParagraph
	Binaries []BinaryParagraph
}

Encapsulation for a debian/control file, which is a series of RFC2822-like blocks, starting with a Source control paragraph, and then a series of Binary control paragraphs.

The debian/control file contains the most vital (and version-independent) information about the source package and about the binary packages it creates.

The first paragraph of the control file contains information about the source package in general. The subsequent sets each describe a binary package that the source tree builds.

func ParseControl

func ParseControl(reader *bufio.Reader, path string) (*Control, error)

Given a bufio.Reader, consume the Reader, and return a Control object for use.

func ParseControlFile

func ParseControlFile(path string) (ret *Control, err error)

Given a path on the filesystem, Parse the file off the disk and return a pointer to a brand new Control struct, unless error is set to a value other than nil.

type DSC

type DSC struct {
	Paragraph

	Filename string

	Format           string
	Source           string
	Binaries         []string          `control:"Binary" delim:","`
	Architectures    []dependency.Arch `control:"Architecture"`
	Version          version.Version
	Origin           string
	Maintainer       string
	Uploaders        []string
	Homepage         string
	StandardsVersion string `control:"Standards-Version"`

	BuildDepends      dependency.Dependency `control:"Build-Depends"`
	BuildDependsArch  dependency.Dependency `control:"Build-Depends-Arch"`
	BuildDependsIndep dependency.Dependency `control:"Build-Depends-Indep"`

	ChecksumsSha1   []SHA1FileHash   `control:"Checksums-Sha1" delim:"\n" strip:"\n\r\t "`
	ChecksumsSha256 []SHA256FileHash `control:"Checksums-Sha256" delim:"\n" strip:"\n\r\t "`
	Files           []MD5FileHash    `control:"Files" delim:"\n" strip:"\n\r\t "`
}

A DSC is the encapsulation of a Debian .dsc control file. This contains information about the source package, and is general handy.

The Debian source control file is generated by dpkg-source when it builds the source archive, from other files in the source package. When unpacking, it is checked against the files and directories in the other parts of the source package.

func OrderDSCForBuild

func OrderDSCForBuild(dscs []DSC, arch dependency.Arch) ([]DSC, error)

Given a bunch of DSC objects, sort the packages topologically by build order by looking at the relationship between the Build-Depends field.

func ParseDsc

func ParseDsc(reader *bufio.Reader, path string) (*DSC, error)

Given a bufio.Reader, consume the Reader, and return a DSC object for use.

func ParseDscFile

func ParseDscFile(path string) (ret *DSC, err error)

Given a path on the filesystem, Parse the file off the disk and return a pointer to a brand new DSC struct, unless error is set to a value other than nil.

func (*DSC) AbsFiles

func (d *DSC) AbsFiles() []MD5FileHash

Return a list of MD5FileHash entries from the `dsc.Files` entry, with the exception that each `Filename` will be joined to the root directory of the DSC file.

func (*DSC) Copy

func (d *DSC) Copy(dest string) error

Copy the .dsc file and all referenced files to the directory listed by the dest argument. This function will error out if the dest argument is not a directory, or if there is an IO operation in transfer.

This function will always move .dsc last, making it suitable to be used to move something into an incoming directory with an inotify hook. This will also mutate DSC.Filename to match the new location.

func (*DSC) DebianSource

func (d *DSC) DebianSource() (string, error)

Return the name of the Debian source. This is assumed to be the first file that contains ".debian." in its name.

func (*DSC) HasArchAll

func (d *DSC) HasArchAll() bool

Check to see if this .dsc contains any arch:all binary packages along with any arch dependent packages.

func (*DSC) Maintainers

func (d *DSC) Maintainers() []string

Return a list of all entities that are responsible for the package's well being. The 0th element is always the package's Maintainer, with any Uploaders following.

func (*DSC) Move

func (d *DSC) Move(dest string) error

Move the .dsc file and all referenced files to the directory listed by the dest argument. This function will error out if the dest argument is not a directory, or if there is an IO operation in transfer.

This function will always move .dsc last, making it suitable to be used to move something into an incoming directory with an inotify hook. This will also mutate DSC.Filename to match the new location.

func (*DSC) Remove

func (d *DSC) Remove() error

Remove the .dsc file and any associated files. This function will always remove the .dsc last, in the event there are filesystem i/o errors on removing associated files.

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

func NewDecoder

func NewDecoder(reader io.Reader, keyring *openpgp.EntityList) (*Decoder, error)

func (*Decoder) Decode

func (d *Decoder) Decode(into interface{}) error

func (*Decoder) Signer

func (d *Decoder) Signer() *openpgp.Entity

type Encoder

type Encoder struct {
	// contains filtered or unexported fields
}

Encoder is a struct that allows for the streaming Encoding of data back out to an `io.Writer`. Most notably, this will separate subsequent `Encode` calls of a Struct with a newline.

It's also worth noting that this *will* also write out elements that were Unmarshaled into a Struct without a member of that name if (and only if) the target Struct contains a `control.Paragraph` anonymous member.

This is handy if the Unmarshaler was given any `X-*` keys that were not present on your Struct.

Given a struct (or list of structs), write to the io.Writer stream in the RFC822-alike Debian control-file format

This code will attempt to unpack it into the struct based on the literal name of the key, This can be overridden by the struct tag `control:""`.

If you're dehydrating a list of strings, you have the option of defining a string to join the tokens with (`delim:", "`).

In order to Marshal a custom Struct, you are required to implement the Marshallable interface. It's highly encouraged to put this interface on the struct without a pointer receiver, so that pass-by-value works when you call Marshal.

func NewEncoder

func NewEncoder(writer io.Writer) (*Encoder, error)

Create a new Encoder, which is configured to write to the given `io.Writer`.

func (*Encoder) Encode

func (e *Encoder) Encode(incoming interface{}) error

Take a Struct, Encode it into a Paragraph, and write that out to the io.Writer set up when the Encoder was configured.

type FileHash

type FileHash struct {
	// cb136f28a8c971d4299cc68e8fdad93a8ca7daf3 1131 dput-ng_1.9.dsc
	Algorithm string
	Hash      string
	Size      int64
	Filename  string
	ByHash    string
}

A FileHash is an entry as found in the Files, Checksum-Sha1, and Checksum-Sha256 entry for the .dsc or .changes files.

func FileHashFromHasher

func FileHashFromHasher(path string, hasher hashio.Hasher) FileHash

func (*FileHash) ByHashPath

func (c *FileHash) ByHashPath(path string) string

ByHashPath returns the corresponding /by-hash/<algorithm>/<hash> path. This function must only be used if the release supports AcquireByHash.

func (*FileHash) Verifier

func (c *FileHash) Verifier() (io.WriteCloser, error)

Verifier returns an io.WriteCloser which verifies the hash of the data being written to it and fails Close() upon hash mismatch.

Example:

verifier := fh.Verifier()
r = io.TeeReader(r, verifier)
if _, err := io.Copy(f, r); err != nil {
    return err
}
if err := verifier.Close(); err != nil {
    return err
}

type FileHashes

type FileHashes []FileHash

type FileListChangesFileHash

type FileListChangesFileHash struct {
	FileHash

	Component string
	Priority  string
}

func (*FileListChangesFileHash) UnmarshalControl

func (c *FileListChangesFileHash) UnmarshalControl(data string) error

type MD5FileHash

type MD5FileHash struct{ FileHash }

func (MD5FileHash) MarshalControl

func (c MD5FileHash) MarshalControl() (string, error)

func (*MD5FileHash) UnmarshalControl

func (c *MD5FileHash) UnmarshalControl(data string) error

type Marshallable

type Marshallable interface {
	MarshalControl() (string, error)
}

The Marshallable interface defines the interface that Marshal will use to do custom dehydration of the Struct back into the Debian 822 format.

type Paragraph

type Paragraph struct {
	Values map[string]string
	Order  []string
}

A Paragraph is a block of RFC2822-like key value pairs. This struct contains two methods to fetch values, a Map called Values, and a Slice called Order, which maintains the ordering as defined in the RFC2822-like block

func ConvertToParagraph

func ConvertToParagraph(incoming interface{}) (*Paragraph, error)

Given a Struct, convert that Struct back into a control.Paragraph. This is not exactly useful as part of the external API, but may be useful in some funny circumstances where you need to treat a Struct you Unmarshaled into as a control.Paragraph again.

In most cases, the Marshal API should be sufficient. Use of this API is mildly discouraged.

func (*Paragraph) Set

func (p *Paragraph) Set(key, value string)

func (*Paragraph) Update

func (p *Paragraph) Update(other Paragraph) Paragraph

func (*Paragraph) WriteTo

func (p *Paragraph) WriteTo(out io.Writer) error

type ParagraphReader

type ParagraphReader struct {
	// contains filtered or unexported fields
}

Wrapper to allow iteration on a set of Paragraphs without consuming them all into memory at one time. This is also the level in which data is signed, so information such as the entity that signed these documents can be read by calling the `.Signer` method on this struct. The next unread Paragraph can be returned by calling the `.Next` method on this struct.

func NewParagraphReader

func NewParagraphReader(reader io.Reader, keyring *openpgp.EntityList) (*ParagraphReader, error)

Create a new ParagraphReader from the given `io.Reader`, and `keyring`. if `keyring` is set to `nil`, this will result in all OpenPGP signature checking being disabled. *including* that the contents match!

Also keep in mind, `reader` may be consumed 100% in memory due to the underlying OpenPGP API being hella fiddly.

func (*ParagraphReader) All

func (p *ParagraphReader) All() ([]Paragraph, error)

func (*ParagraphReader) Next

func (p *ParagraphReader) Next() (*Paragraph, error)

Consume the io.Reader and return the next parsed Paragraph, modulo garbage lines causing us to return an error.

func (*ParagraphReader) Signer

func (p *ParagraphReader) Signer() *openpgp.Entity

Return the Entity (if one exists) that signed this set of Paragraphs.

type SHA1FileHash

type SHA1FileHash struct{ FileHash }

func (SHA1FileHash) MarshalControl

func (c SHA1FileHash) MarshalControl() (string, error)

func (*SHA1FileHash) UnmarshalControl

func (c *SHA1FileHash) UnmarshalControl(data string) error

type SHA256FileHash

type SHA256FileHash struct{ FileHash }

func (SHA256FileHash) MarshalControl

func (c SHA256FileHash) MarshalControl() (string, error)

func (*SHA256FileHash) UnmarshalControl

func (c *SHA256FileHash) UnmarshalControl(data string) error

type SHA512FileHash

type SHA512FileHash struct{ FileHash }

func (SHA512FileHash) MarshalControl

func (c SHA512FileHash) MarshalControl() (string, error)

func (*SHA512FileHash) UnmarshalControl

func (c *SHA512FileHash) UnmarshalControl(data string) error

type SourceIndex

type SourceIndex struct {
	Paragraph

	Package  string
	Binaries []string `control:"Binary" delim:","`

	Version    version.Version
	Maintainer string
	Uploaders  string `delim:","`

	Architecture []dependency.Arch

	StandardsVersion string
	Format           string
	Files            []MD5FileHash    `delim:"\n" strip:"\n\r\t "`
	VcsBrowser       string           `control:"Vcs-Browser"`
	VcsGit           string           `control:"Vcs-Git"`
	VcsSvn           string           `control:"Vcs-Svn"`
	VcsBzr           string           `control:"Vcs-Bzr"`
	ChecksumsSha1    []SHA1FileHash   `control:"Checksums-Sha1" delim:"\n" strip:"\n\r\t "`
	ChecksumsSha256  []SHA256FileHash `control:"Checksums-Sha256" delim:"\n" strip:"\n\r\t "`
	Homepage         string
	Directory        string
	Priority         string
	Section          string
}

The SourceIndex struct represents the exported APT Source index file, as seen on Debian (and Debian derived) mirrors, as well as the cached version in /var/lib/apt/lists/.

This can be used to examine Source packages, to examine things like Binary packages built by Source packages, who maintains a package, or where to find the VCS repo for that package.

func ParseSourceIndex

func ParseSourceIndex(reader *bufio.Reader) (ret []SourceIndex, err error)

Given a reader, parse out a list of SourceIndex structs.

func (*SourceIndex) GetBuildDepends

func (index *SourceIndex) GetBuildDepends() dependency.Dependency

Parse the Depends Build-Depends relation on this package.

func (*SourceIndex) GetBuildDependsArch

func (index *SourceIndex) GetBuildDependsArch() dependency.Dependency

Parse the Depends Build-Depends-Arch relation on this package.

func (*SourceIndex) GetBuildDependsIndep

func (index *SourceIndex) GetBuildDependsIndep() dependency.Dependency

Parse the Depends Build-Depends-Indep relation on this package.

type SourceParagraph

type SourceParagraph struct {
	Paragraph

	Maintainer  string
	Uploaders   []string `delim:","`
	Source      string
	Priority    string
	Section     string
	Description string

	BuildDepends        dependency.Dependency `control:"Build-Depends"`
	BuildDependsIndep   dependency.Dependency `control:"Build-Depends-Indep"`
	BuildConflicts      dependency.Dependency `control:"Build-Conflicts"`
	BuildConflictsIndep dependency.Dependency `control:"Build-Conflicts-Indep"`
}

Encapsulation for a debian/control Source entry. This contains information that will wind up in the .dsc and friends. Really quite fun!

func (*SourceParagraph) Maintainers

func (s *SourceParagraph) Maintainers() []string

Return a list of all entities that are responsible for the package's well being. The 0th element is always the package's Maintainer, with any Uploaders following.

type Unmarshallable

type Unmarshallable interface {
	UnmarshalControl(data string) error
}

The Unmarshallable interface defines the interface that Unmarshal will use to do custom unpacks into Structs.

The argument passed in will be a string that contains the value of the RFC822 key this object relates to.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL