| 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 |
| } |