blob: a0a3fdc52cdf50b426e036bfc16fe822a6d8db2b [file] [log] [blame]
package repo
import (
"encoding/xml"
"io"
"io/ioutil"
)
// Manifest is the root element of the file.
//
// The order of the fields in this struct is the order they will be written by
// xml.Marshal.
//
// Some fields of Manifest and its children have been omitted. For full documentation of
// the Repo manifest structure, see: go/repo-manifests-explained.
type Manifest struct {
XMLName xml.Name `xml:"manifest"`
Comment string `xml:",comment"`
Remote []Remote `xml:"remote"`
Default Default `xml:"default"`
Project []Project `xml:"project"`
}
// Default holds default values for Project element attributes.
//
// The revision attribute is represented by `Branch` instead of `Revision` because the
// value is always a branch name. "revision" is a misnomer in the Repo manifest schema.
type Default struct {
// Name of a Git branch (e.g. master or refs/heads/master). Project elements lacking
// their own revision attribute will use this value.
Branch string `xml:"revision,attr,omitempty"`
// Name of a previously defined remote element. Project elements lacking a remote
// attribute of their own will use this remote.
Remote string `xml:"remote,attr,omitempty"`
}
// Remote specifies a Git URL and review server shared by one or more repos.
type Remote struct {
// A short name unique to this manifest file. The name specified here is used as the
// remote name in each project's .git/config, and is therefore automatically available
// to commands like git fetch, git remote, git pull and git push.
Name string `xml:"name,attr,omitempty"`
// The Git URL prefix for all projects which use this remote. Each project's name is
// appended to this prefix to form the actual URL used to clone the project.
Fetch string `xml:"fetch,attr,omitempty"`
// Hostname of the Gerrit server where reviews are uploaded to by repo upload. This
// attribute is optional; if not specified then repo upload will not function.
Review string `xml:"review,attr,omitempty"`
// Revision omitted; Project elements will contain a revision if necessary.
}
// Project represents a single Git repository
type Project struct {
// Name is the name of this project.
Name string `xml:"name,attr,omitempty"`
// Path is an optional path relative to the top directory of the repo client where the
// Git working directory for this project should be placed. If not supplied the
// project name is used. If the project has a parent element, its path will be
// prefixed by the parent's.
Path string `xml:"path,attr,omitempty"`
// Remote is the name of a previously defined remote element. If not supplied the
// remote given by the default element is used.
Remote string `xml:"remote,attr,omitempty"`
// Revision is the name of the Git branch the manifest wants to track for this
// project. Names can be relative to refs/heads (e.g. just master) or absolute (e.g.
// refs/heads/master). Tags and/or explicit SHA-1s should work in theory, but have not
// been extensively tested. If not supplied the revision given by the remote element
// is used if applicable, else the default element is used.
Revision string `xml:"revision,attr,omitempty"`
}
// ParseManifest parses a Manifest from the given io.Reader.
func ParseManifest(r io.Reader, into *Manifest) error {
bytes, err := ioutil.ReadAll(r)
if err != nil {
return err
}
return xml.Unmarshal(bytes, into)
}
// WriteManifest writes the given Manifest to the given io.Writer.
func WriteManifest(w io.Writer, m *Manifest) error {
bytes, err := xml.MarshalIndent(m, "", " ")
if err != nil {
return err
}
if _, err := w.Write([]byte(xml.Header)); err != nil {
return err
}
if _, err := w.Write(bytes); err != nil {
return err
}
return nil
}