github.com/coreos/mantle@v0.13.0/sdk/repo/manifest.go (about)

     1  // Copyright 2016 CoreOS, Inc.
     2  // Copyright 2008 The Android Open Source Project
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  // repo is a limited implementation of the python repo git front end.
    17  //
    18  // Manifest Format
    19  //
    20  // A repo manifest describes the structure of a repo client; that is
    21  // the directories that are visible and where they should be obtained
    22  // from with git.
    23  //
    24  // The basic structure of a manifest is a bare Git repository holding
    25  // a single 'default.xml' XML file in the top level directory.
    26  //
    27  // Manifests are inherently version controlled, since they are kept
    28  // within a Git repository.  Updates to manifests are automatically
    29  // obtained by clients during `repo sync`.
    30  //
    31  // A manifest XML file (e.g. 'default.xml') roughly conforms to the
    32  // following DTD. The python code is the only authoritative source.
    33  //
    34  // Local Manifests
    35  //
    36  // Additional remotes and projects may be added through local manifest
    37  // files stored in `$TOP_DIR/.repo/local_manifests/*.xml`.
    38  //
    39  // For example:
    40  //
    41  //   $ ls .repo/local_manifests
    42  //   local_manifest.xml
    43  //   another_local_manifest.xml
    44  //
    45  //   $ cat .repo/local_manifests/local_manifest.xml
    46  //   <?xml version="1.0" encoding="UTF-8"?>
    47  //   <manifest>
    48  //     <project path="manifest"
    49  //              name="tools/manifest" />
    50  //     <project path="platform-manifest"
    51  //              name="platform/manifest" />
    52  //   </manifest>
    53  //
    54  // Users may add projects to the local manifest(s) prior to a `repo sync`
    55  // invocation, instructing repo to automatically download and manage
    56  // these extra projects.
    57  //
    58  // Manifest files stored in `$TOP_DIR/.repo/local_manifests/*.xml` will
    59  // be loaded in alphabetical order.
    60  //
    61  // Additional remotes and projects may also be added through a local
    62  // manifest, stored in `$TOP_DIR/.repo/local_manifest.xml`. This method
    63  // is deprecated in favor of using multiple manifest files as mentioned
    64  // above.
    65  //
    66  // If `$TOP_DIR/.repo/local_manifest.xml` exists, it will be loaded before
    67  // any manifest files stored in `$TOP_DIR/.repo/local_manifests/*.xml`.
    68  package repo
    69  
    70  import (
    71  	"encoding/xml"
    72  )
    73  
    74  // Manifest is the root element of the file.
    75  //
    76  //    <!ELEMENT manifest (include*,
    77  //                        notice?,
    78  //                        remote*,
    79  //                        default?,
    80  //                        manifest-server?,
    81  //                        project*,
    82  //                        extend-project*,
    83  //                        remove-project*,
    84  //                        repo-hooks?)>
    85  //
    86  //    <!ELEMENT notice (#PCDATA)>
    87  //
    88  type Manifest struct {
    89  	XMLName        xml.Name        `xml:"manifest"`
    90  	Includes       []Include       `xml:"include"`
    91  	Notice         string          `xml:"notice"`
    92  	Remotes        []Remote        `xml:"remote"`
    93  	Default        *Default        `xml:"default"`
    94  	ManifestServer *ManifestServer `xml:"manifest-server"`
    95  	Projects       []Project       `xml:"project"`
    96  	ExtendProjects []ExtendProject `xml:"extend-project"`
    97  	RemoveProjects []RemoveProject `xml:"remove-project"`
    98  	RepoHooks      *RepoHooks      `xml:"repo-hooks"`
    99  }
   100  
   101  // Remote
   102  //
   103  //    <!ELEMENT remote (EMPTY)>
   104  //    <!ATTLIST remote name         ID    #REQUIRED>
   105  //    <!ATTLIST remote alias        CDATA #IMPLIED>
   106  //    <!ATTLIST remote fetch        CDATA #REQUIRED>
   107  //    <!ATTLIST remote review       CDATA #IMPLIED>
   108  //    <!ATTLIST remote revision     CDATA #IMPLIED>
   109  //
   110  // One or more remote elements may be specified.  Each remote element
   111  // specifies a Git URL shared by one or more projects and (optionally)
   112  // the Gerrit review server those projects upload changes through.
   113  //
   114  // Attribute `name`: A short name unique to this manifest file.  The
   115  // name specified here is used as the remote name in each project's
   116  // .git/config, and is therefore automatically available to commands
   117  // like `git fetch`, `git remote`, `git pull` and `git push`.
   118  //
   119  // Attribute `alias`: The alias, if specified, is used to override
   120  // `name` to be set as the remote name in each project's .git/config.
   121  // Its value can be duplicated while attribute `name` has to be unique
   122  // in the manifest file. This helps each project to be able to have
   123  // same remote name which actually points to different remote url.
   124  //
   125  // Attribute `fetch`: The Git URL prefix for all projects which use
   126  // this remote.  Each project's name is appended to this prefix to
   127  // form the actual URL used to clone the project.
   128  //
   129  // Attribute `review`: Hostname of the Gerrit server where reviews
   130  // are uploaded to by `repo upload`.  This attribute is optional;
   131  // if not specified then `repo upload` will not function.
   132  //
   133  // Attribute `revision`: Name of a Git branch (e.g. `master` or
   134  // `refs/heads/master`). Remotes with their own revision will override
   135  // the default revision.
   136  //
   137  type Remote struct {
   138  	Name     string `xml:"name,attr"`
   139  	Alias    string `xml:"alias,attr,omitempty"`
   140  	Fetch    string `xml:"fetch,attr"`
   141  	Review   string `xml:"review,attr,omitempty"`
   142  	Revision string `xml:"revision,attr,omitempty"`
   143  }
   144  
   145  // Default
   146  //
   147  //    <!ELEMENT default (EMPTY)>
   148  //    <!ATTLIST default remote      IDREF #IMPLIED>
   149  //    <!ATTLIST default revision    CDATA #IMPLIED>
   150  //    <!ATTLIST default dest-branch CDATA #IMPLIED>
   151  //    <!ATTLIST default sync-j      CDATA #IMPLIED>
   152  //    <!ATTLIST default sync-c      CDATA #IMPLIED>
   153  //    <!ATTLIST default sync-s      CDATA #IMPLIED>
   154  //
   155  // At most one default element may be specified.  Its remote and
   156  // revision attributes are used when a project element does not
   157  // specify its own remote or revision attribute.
   158  //
   159  // Attribute `remote`: Name of a previously defined remote element.
   160  // Project elements lacking a remote attribute of their own will use
   161  // this remote.
   162  //
   163  // Attribute `revision`: Name of a Git branch (e.g. `master` or
   164  // `refs/heads/master`).  Project elements lacking their own
   165  // revision attribute will use this revision.
   166  //
   167  // Attribute `dest-branch`: Name of a Git branch (e.g. `master`).
   168  // Project elements not setting their own `dest-branch` will inherit
   169  // this value. If this value is not set, projects will use `revision`
   170  // by default instead.
   171  //
   172  // Attribute `sync-j`: Number of parallel jobs to use when synching.
   173  //
   174  // Attribute `sync-c`: Set to true to only sync the given Git
   175  // branch (specified in the `revision` attribute) rather than the
   176  // whole ref space.  Project elements lacking a sync-c element of
   177  // their own will use this value.
   178  //
   179  // Attribute `sync-s`: Set to true to also sync sub-projects.
   180  //
   181  type Default struct {
   182  	Remote          string `xml:"remote,attr,omitempty"`
   183  	Revision        string `xml:"revision,attr,omitempty"`
   184  	DestBranch      string `xml:"dest-branch,attr,omitempty"`
   185  	SyncJobs        string `xml:"sync-j,attr,omitempty"`
   186  	SyncBranch      string `xml:"sync-c,attr,omitempty"`
   187  	SyncSubProjects string `xml:"sync-s,attr,omitempty"`
   188  }
   189  
   190  // ManifestServer
   191  //
   192  //    <!ELEMENT manifest-server (EMPTY)>
   193  //    <!ATTLIST url              CDATA #REQUIRED>
   194  //
   195  // At most one manifest-server may be specified. The url attribute
   196  // is used to specify the URL of a manifest server, which is an
   197  // XML RPC service.
   198  //
   199  // The manifest server should implement the following RPC methods:
   200  //
   201  //   GetApprovedManifest(branch, target)
   202  //
   203  // Return a manifest in which each project is pegged to a known good revision
   204  // for the current branch and target.
   205  //
   206  // The target to use is defined by environment variables TARGET_PRODUCT
   207  // and TARGET_BUILD_VARIANT. These variables are used to create a string
   208  // of the form $TARGET_PRODUCT-$TARGET_BUILD_VARIANT, e.g. passion-userdebug.
   209  // If one of those variables or both are not present, the program will call
   210  // GetApprovedManifest without the target parameter and the manifest server
   211  // should choose a reasonable default target.
   212  //
   213  //   GetManifest(tag)
   214  //
   215  // Return a manifest in which each project is pegged to the revision at
   216  // the specified tag.
   217  //
   218  type ManifestServer struct {
   219  	URL string `xml:"url,attr"`
   220  }
   221  
   222  // Project
   223  //
   224  //    <!ELEMENT project (annotation*,
   225  //                       project*,
   226  //                       copyfile*,
   227  //                       linkfile*)>
   228  //    <!ATTLIST project name        CDATA #REQUIRED>
   229  //    <!ATTLIST project path        CDATA #IMPLIED>
   230  //    <!ATTLIST project remote      IDREF #IMPLIED>
   231  //    <!ATTLIST project revision    CDATA #IMPLIED>
   232  //    <!ATTLIST project dest-branch CDATA #IMPLIED>
   233  //    <!ATTLIST project groups      CDATA #IMPLIED>
   234  //    <!ATTLIST project sync-c      CDATA #IMPLIED>
   235  //    <!ATTLIST project sync-s      CDATA #IMPLIED>
   236  //    <!ATTLIST project upstream    CDATA #IMPLIED>
   237  //    <!ATTLIST project clone-depth CDATA #IMPLIED>
   238  //    <!ATTLIST project force-path  CDATA #IMPLIED>
   239  //
   240  // One or more project elements may be specified.  Each element
   241  // describes a single Git repository to be cloned into the repo
   242  // client workspace.  You may specify Git-submodules by creating a
   243  // nested project.  Git-submodules will be automatically
   244  // recognized and inherit their parent's attributes, but those
   245  // may be overridden by an explicitly specified project element.
   246  //
   247  // Attribute `name`: A unique name for this project.  The project's
   248  // name is appended onto its remote's fetch URL to generate the actual
   249  // URL to configure the Git remote with.  The URL gets formed as:
   250  //
   251  //   ${remote_fetch}/${project_name}.git
   252  //
   253  // where ${remote_fetch} is the remote's fetch attribute and
   254  // ${project_name} is the project's name attribute.  The suffix ".git"
   255  // is always appended as repo assumes the upstream is a forest of
   256  // bare Git repositories.  If the project has a parent element, its
   257  // name will be prefixed by the parent's.
   258  //
   259  // The project name must match the name Gerrit knows, if Gerrit is
   260  // being used for code reviews.
   261  //
   262  // Attribute `path`: An optional path relative to the top directory
   263  // of the repo client where the Git working directory for this project
   264  // should be placed.  If not supplied the project name is used.
   265  // If the project has a parent element, its path will be prefixed
   266  // by the parent's.
   267  //
   268  // Attribute `remote`: Name of a previously defined remote element.
   269  // If not supplied the remote given by the default element is used.
   270  //
   271  // Attribute `revision`: Name of the Git branch the manifest wants
   272  // to track for this project.  Names can be relative to refs/heads
   273  // (e.g. just "master") or absolute (e.g. "refs/heads/master").
   274  // Tags and/or explicit SHA-1s should work in theory, but have not
   275  // been extensively tested.  If not supplied the revision given by
   276  // the remote element is used if applicable, else the default
   277  // element is used.
   278  //
   279  // Attribute `dest-branch`: Name of a Git branch (e.g. `master`).
   280  // When using `repo upload`, changes will be submitted for code
   281  // review on this branch. If unspecified both here and in the
   282  // default element, `revision` is used instead.
   283  //
   284  // Attribute `groups`: List of groups to which this project belongs,
   285  // whitespace or comma separated.  All projects belong to the group
   286  // "all", and each project automatically belongs to a group of
   287  // its name:`name` and path:`path`.  E.g. for
   288  // <project name="monkeys" path="barrel-of"/>, that project
   289  // definition is implicitly in the following manifest groups:
   290  // default, name:monkeys, and path:barrel-of.  If you place a project in the
   291  // group "notdefault", it will not be automatically downloaded by repo.
   292  // If the project has a parent element, the `name` and `path` here
   293  // are the prefixed ones.
   294  //
   295  // Attribute `sync-c`: Set to true to only sync the given Git
   296  // branch (specified in the `revision` attribute) rather than the
   297  // whole ref space.
   298  //
   299  // Attribute `sync-s`: Set to true to also sync sub-projects.
   300  //
   301  // Attribute `upstream`: Name of the Git ref in which a sha1
   302  // can be found.  Used when syncing a revision locked manifest in
   303  // -c mode to avoid having to sync the entire ref space.
   304  //
   305  // Attribute `clone-depth`: Set the depth to use when fetching this
   306  // project.  If specified, this value will override any value given
   307  // to repo init with the --depth option on the command line.
   308  //
   309  // Attribute `force-path`: Set to true to force this project to create the
   310  // local mirror repository according to its `path` attribute (if supplied)
   311  // rather than the `name` attribute.  This attribute only applies to the
   312  // local mirrors syncing, it will be ignored when syncing the projects in a
   313  // client working directory.
   314  //
   315  type Project struct {
   316  	Annotations     []Annotation `xml:"annotation"`
   317  	SubProjects     []Project    `xml:"project"`
   318  	CopyFiles       []CopyFile   `xml:"copyfile"`
   319  	LinkFiles       []LinkFile   `xml:"linkfile"`
   320  	Name            string       `xml:"name,attr"`
   321  	Path            string       `xml:"path,attr,omitempty"`
   322  	Remote          string       `xml:"remote,attr,omitempty"`
   323  	Revision        string       `xml:"revision,attr,omitempty"`
   324  	DestBranch      string       `xml:"dest-branch,attr,omitempty"`
   325  	Groups          string       `xml:"groups,attr,omitempty"`
   326  	SyncBranch      string       `xml:"sync-c,attr,omitempty"`
   327  	SyncSubProjects string       `xml:"sync-s,attr,omitempty"`
   328  	Upstream        string       `xml:"upstream,attr,omitempty"`
   329  	CloneDepth      string       `xml:"clone-depth,attr,omitempty"`
   330  	ForcePath       string       `xml:"force-path,attr,omitempty"`
   331  }
   332  
   333  // ExtendProject
   334  //
   335  //    <!ELEMENT extend-project>
   336  //    <!ATTLIST extend-project name   CDATA #REQUIRED>
   337  //    <!ATTLIST extend-project path   CDATA #IMPLIED>
   338  //    <!ATTLIST extend-project groups CDATA #IMPLIED>
   339  //
   340  // Modify the attributes of the named project.
   341  //
   342  // This element is mostly useful in a local manifest file, to modify the
   343  // attributes of an existing project without completely replacing the
   344  // existing project definition.  This makes the local manifest more robust
   345  // against changes to the original manifest.
   346  //
   347  // Attribute `path`: If specified, limit the change to projects checked out
   348  // at the specified path, rather than all projects with the given name.
   349  //
   350  // Attribute `groups`: List of additional groups to which this project
   351  // belongs.  Same syntax as the corresponding element of `project`.
   352  //
   353  type ExtendProject struct {
   354  	Name   string `xml:"name,attr"`
   355  	Path   string `xml:"path,attr,omitempty"`
   356  	Groups string `xml:"groups,attr,omitempty"`
   357  }
   358  
   359  // Annotation
   360  //
   361  //    <!ELEMENT annotation (EMPTY)>
   362  //    <!ATTLIST annotation name  CDATA #REQUIRED>
   363  //    <!ATTLIST annotation value CDATA #REQUIRED>
   364  //    <!ATTLIST annotation keep  CDATA "true">
   365  //
   366  // Zero or more annotation elements may be specified as children of a
   367  // project element. Each element describes a name-value pair that will be
   368  // exported into each project's environment during a 'forall' command,
   369  // prefixed with REPO__.  In addition, there is an optional attribute
   370  // "keep" which accepts the case insensitive values "true" (default) or
   371  // "false".  This attribute determines whether or not the annotation will
   372  // be kept when exported with the manifest subcommand.
   373  //
   374  type Annotation struct {
   375  	Name  string `xml:"name,attr"`
   376  	Value string `xml:"value,attr"`
   377  	Keep  string `xml:"keep,attr,omitempty"`
   378  }
   379  
   380  // CopyFile
   381  //
   382  //    <!ELEMENT copyfile (EMPTY)>
   383  //    <!ATTLIST src value  CDATA #REQUIRED>
   384  //    <!ATTLIST dest value CDATA #REQUIRED>
   385  //
   386  // Zero or more copyfile elements may be specified as children of a
   387  // project element. Each element describes a src-dest pair of files;
   388  // the "src" file will be copied to the "dest" place during 'repo sync'
   389  // command.
   390  // "src" is project relative, "dest" is relative to the top of the tree.
   391  //
   392  type CopyFile struct {
   393  	Src  string `xml:"src,attr"`
   394  	Dest string `xml:"dest,attr"`
   395  }
   396  
   397  // LinkFile
   398  //
   399  //    <!ELEMENT linkfile (EMPTY)>
   400  //    <!ATTLIST src value  CDATA #REQUIRED>
   401  //    <!ATTLIST dest value CDATA #REQUIRED>
   402  //
   403  // It's just like copyfile and runs at the same time as copyfile but
   404  // instead of copying it creates a symlink.
   405  //
   406  type LinkFile struct {
   407  	Src  string `xml:"src,attr"`
   408  	Dest string `xml:"dest,attr"`
   409  }
   410  
   411  // RemoveProject
   412  //
   413  //    <!ELEMENT remove-project (EMPTY)>
   414  //    <!ATTLIST remove-project name CDATA #REQUIRED>
   415  //
   416  // Deletes the named project from the internal manifest table, possibly
   417  // allowing a subsequent project element in the same manifest file to
   418  // replace the project with a different source.
   419  //
   420  // This element is mostly useful in a local manifest file, where
   421  // the user can remove a project, and possibly replace it with their
   422  // own definition.
   423  //
   424  type RemoveProject struct {
   425  	Name string `xml:"name,attr"`
   426  }
   427  
   428  // RepoHooks
   429  //
   430  //    <!ELEMENT repo-hooks (EMPTY)>
   431  //    <!ATTLIST repo-hooks in-project   CDATA #REQUIRED>
   432  //    <!ATTLIST repo-hooks enabled-list CDATA #REQUIRED>
   433  //
   434  type RepoHooks struct {
   435  	InProject   string `xml:"in-project,attr"`
   436  	EnabledList string `xml:"enabled-list,attr"`
   437  }
   438  
   439  // Include
   440  //
   441  //    <!ELEMENT include      (EMPTY)>
   442  //    <!ATTLIST include name CDATA #REQUIRED>
   443  //
   444  // This element provides the capability of including another manifest
   445  // file into the originating manifest.  Normal rules apply for the
   446  // target manifest to include - it must be a usable manifest on its own.
   447  //
   448  // Attribute `name`: the manifest to include, specified relative to
   449  // the manifest repository's root.
   450  //
   451  type Include struct {
   452  	Name string `xml:"name,attr"`
   453  }