mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
Create an abstract Manifest base class
This will help as we add support for another manifest type. Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
parent
ca3d8ff4fc
commit
f1a6b14fdc
10
command.py
10
command.py
@ -17,6 +17,8 @@ import os
|
|||||||
import optparse
|
import optparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import manifest_loader
|
||||||
|
|
||||||
from error import NoSuchProjectError
|
from error import NoSuchProjectError
|
||||||
|
|
||||||
class Command(object):
|
class Command(object):
|
||||||
@ -24,7 +26,6 @@ class Command(object):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
common = False
|
common = False
|
||||||
manifest = None
|
|
||||||
_optparse = None
|
_optparse = None
|
||||||
|
|
||||||
def WantPager(self, opt):
|
def WantPager(self, opt):
|
||||||
@ -57,6 +58,13 @@ class Command(object):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def manifest(self):
|
||||||
|
return self.GetManifest()
|
||||||
|
|
||||||
|
def GetManifest(self, reparse=False):
|
||||||
|
return manifest_loader.GetManifest(self.repodir, reparse)
|
||||||
|
|
||||||
def GetProjects(self, args, missing_ok=False):
|
def GetProjects(self, args, missing_ok=False):
|
||||||
"""A list of projects that match the arguments.
|
"""A list of projects that match the arguments.
|
||||||
"""
|
"""
|
||||||
|
4
main.py
4
main.py
@ -32,11 +32,9 @@ from git_config import close_ssh
|
|||||||
from command import InteractiveCommand
|
from command import InteractiveCommand
|
||||||
from command import MirrorSafeCommand
|
from command import MirrorSafeCommand
|
||||||
from command import PagedCommand
|
from command import PagedCommand
|
||||||
from editor import Editor
|
|
||||||
from error import ManifestInvalidRevisionError
|
from error import ManifestInvalidRevisionError
|
||||||
from error import NoSuchProjectError
|
from error import NoSuchProjectError
|
||||||
from error import RepoChangedException
|
from error import RepoChangedException
|
||||||
from manifest_xml import XmlManifest
|
|
||||||
from pager import RunPager
|
from pager import RunPager
|
||||||
|
|
||||||
from subcmds import all as all_commands
|
from subcmds import all as all_commands
|
||||||
@ -97,8 +95,6 @@ class _Repo(object):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
cmd.repodir = self.repodir
|
cmd.repodir = self.repodir
|
||||||
cmd.manifest = XmlManifest(cmd.repodir)
|
|
||||||
Editor.globalConfig = cmd.manifest.globalConfig
|
|
||||||
|
|
||||||
if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror:
|
if not isinstance(cmd, MirrorSafeCommand) and cmd.manifest.IsMirror:
|
||||||
print >>sys.stderr, \
|
print >>sys.stderr, \
|
||||||
|
37
manifest.py
Normal file
37
manifest.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2009 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from editor import Editor
|
||||||
|
from git_config import GitConfig
|
||||||
|
from project import MetaProject
|
||||||
|
|
||||||
|
class Manifest(object):
|
||||||
|
"""any manifest format"""
|
||||||
|
|
||||||
|
def __init__(self, repodir):
|
||||||
|
self.repodir = os.path.abspath(repodir)
|
||||||
|
self.topdir = os.path.dirname(self.repodir)
|
||||||
|
self.globalConfig = GitConfig.ForUser()
|
||||||
|
Editor.globalConfig = self.globalConfig
|
||||||
|
|
||||||
|
self.repoProject = MetaProject(self, 'repo',
|
||||||
|
gitdir = os.path.join(repodir, 'repo/.git'),
|
||||||
|
worktree = os.path.join(repodir, 'repo'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def IsMirror(self):
|
||||||
|
return self.manifestProject.config.GetBoolean('repo.mirror')
|
27
manifest_loader.py
Normal file
27
manifest_loader.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2009 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from manifest_xml import XmlManifest
|
||||||
|
|
||||||
|
def ParseManifest(repodir):
|
||||||
|
return XmlManifest(repodir)
|
||||||
|
|
||||||
|
_manifest = None
|
||||||
|
|
||||||
|
def GetManifest(repodir, reparse=False):
|
||||||
|
global _manifest
|
||||||
|
if _manifest is None or reparse:
|
||||||
|
_manifest = ParseManifest(repodir)
|
||||||
|
return _manifest
|
@ -18,6 +18,7 @@ import sys
|
|||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
|
|
||||||
from git_config import GitConfig, IsId
|
from git_config import GitConfig, IsId
|
||||||
|
from manifest import Manifest
|
||||||
from project import RemoteSpec, Project, MetaProject, R_HEADS, HEAD
|
from project import RemoteSpec, Project, MetaProject, R_HEADS, HEAD
|
||||||
from error import ManifestParseError
|
from error import ManifestParseError
|
||||||
|
|
||||||
@ -46,19 +47,13 @@ class _XmlRemote(object):
|
|||||||
url += '/%s.git' % projectName
|
url += '/%s.git' % projectName
|
||||||
return RemoteSpec(self.name, url, self.reviewUrl)
|
return RemoteSpec(self.name, url, self.reviewUrl)
|
||||||
|
|
||||||
class XmlManifest(object):
|
class XmlManifest(Manifest):
|
||||||
"""manages the repo configuration file"""
|
"""manages the repo configuration file"""
|
||||||
|
|
||||||
def __init__(self, repodir):
|
def __init__(self, repodir):
|
||||||
self.repodir = os.path.abspath(repodir)
|
Manifest.__init__(self, repodir)
|
||||||
self.topdir = os.path.dirname(self.repodir)
|
|
||||||
self.manifestFile = os.path.join(self.repodir, MANIFEST_FILE_NAME)
|
|
||||||
self.globalConfig = GitConfig.ForUser()
|
|
||||||
|
|
||||||
self.repoProject = MetaProject(self, 'repo',
|
|
||||||
gitdir = os.path.join(repodir, 'repo/.git'),
|
|
||||||
worktree = os.path.join(repodir, 'repo'))
|
|
||||||
|
|
||||||
|
self._manifestFile = os.path.join(repodir, MANIFEST_FILE_NAME)
|
||||||
self.manifestProject = MetaProject(self, 'manifests',
|
self.manifestProject = MetaProject(self, 'manifests',
|
||||||
gitdir = os.path.join(repodir, 'manifests.git'),
|
gitdir = os.path.join(repodir, 'manifests.git'),
|
||||||
worktree = os.path.join(repodir, 'manifests'))
|
worktree = os.path.join(repodir, 'manifests'))
|
||||||
@ -72,18 +67,18 @@ class XmlManifest(object):
|
|||||||
if not os.path.isfile(path):
|
if not os.path.isfile(path):
|
||||||
raise ManifestParseError('manifest %s not found' % name)
|
raise ManifestParseError('manifest %s not found' % name)
|
||||||
|
|
||||||
old = self.manifestFile
|
old = self._manifestFile
|
||||||
try:
|
try:
|
||||||
self.manifestFile = path
|
self._manifestFile = path
|
||||||
self._Unload()
|
self._Unload()
|
||||||
self._Load()
|
self._Load()
|
||||||
finally:
|
finally:
|
||||||
self.manifestFile = old
|
self._manifestFile = old
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if os.path.exists(self.manifestFile):
|
if os.path.exists(self._manifestFile):
|
||||||
os.remove(self.manifestFile)
|
os.remove(self._manifestFile)
|
||||||
os.symlink('manifests/%s' % name, self.manifestFile)
|
os.symlink('manifests/%s' % name, self._manifestFile)
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
raise ManifestParseError('cannot link manifest %s' % name)
|
raise ManifestParseError('cannot link manifest %s' % name)
|
||||||
|
|
||||||
@ -168,10 +163,6 @@ class XmlManifest(object):
|
|||||||
self._Load()
|
self._Load()
|
||||||
return self._default
|
return self._default
|
||||||
|
|
||||||
@property
|
|
||||||
def IsMirror(self):
|
|
||||||
return self.manifestProject.config.GetBoolean('repo.mirror')
|
|
||||||
|
|
||||||
def _Unload(self):
|
def _Unload(self):
|
||||||
self._loaded = False
|
self._loaded = False
|
||||||
self._projects = {}
|
self._projects = {}
|
||||||
@ -192,11 +183,11 @@ class XmlManifest(object):
|
|||||||
local = os.path.join(self.repodir, LOCAL_MANIFEST_NAME)
|
local = os.path.join(self.repodir, LOCAL_MANIFEST_NAME)
|
||||||
if os.path.exists(local):
|
if os.path.exists(local):
|
||||||
try:
|
try:
|
||||||
real = self.manifestFile
|
real = self._manifestFile
|
||||||
self.manifestFile = local
|
self._manifestFile = local
|
||||||
self._ParseManifest(False)
|
self._ParseManifest(False)
|
||||||
finally:
|
finally:
|
||||||
self.manifestFile = real
|
self._manifestFile = real
|
||||||
|
|
||||||
if self.IsMirror:
|
if self.IsMirror:
|
||||||
self._AddMetaProjectMirror(self.repoProject)
|
self._AddMetaProjectMirror(self.repoProject)
|
||||||
@ -205,17 +196,17 @@ class XmlManifest(object):
|
|||||||
self._loaded = True
|
self._loaded = True
|
||||||
|
|
||||||
def _ParseManifest(self, is_root_file):
|
def _ParseManifest(self, is_root_file):
|
||||||
root = xml.dom.minidom.parse(self.manifestFile)
|
root = xml.dom.minidom.parse(self._manifestFile)
|
||||||
if not root or not root.childNodes:
|
if not root or not root.childNodes:
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
"no root node in %s" % \
|
"no root node in %s" % \
|
||||||
self.manifestFile
|
self._manifestFile
|
||||||
|
|
||||||
config = root.childNodes[0]
|
config = root.childNodes[0]
|
||||||
if config.nodeName != 'manifest':
|
if config.nodeName != 'manifest':
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
"no <manifest> in %s" % \
|
"no <manifest> in %s" % \
|
||||||
self.manifestFile
|
self._manifestFile
|
||||||
|
|
||||||
for node in config.childNodes:
|
for node in config.childNodes:
|
||||||
if node.nodeName == 'remove-project':
|
if node.nodeName == 'remove-project':
|
||||||
@ -233,7 +224,7 @@ class XmlManifest(object):
|
|||||||
if self._remotes.get(remote.name):
|
if self._remotes.get(remote.name):
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
'duplicate remote %s in %s' % \
|
'duplicate remote %s in %s' % \
|
||||||
(remote.name, self.manifestFile)
|
(remote.name, self._manifestFile)
|
||||||
self._remotes[remote.name] = remote
|
self._remotes[remote.name] = remote
|
||||||
|
|
||||||
for node in config.childNodes:
|
for node in config.childNodes:
|
||||||
@ -241,7 +232,7 @@ class XmlManifest(object):
|
|||||||
if self._default is not None:
|
if self._default is not None:
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
'duplicate default in %s' % \
|
'duplicate default in %s' % \
|
||||||
(self.manifestFile)
|
(self._manifestFile)
|
||||||
self._default = self._ParseDefault(node)
|
self._default = self._ParseDefault(node)
|
||||||
if self._default is None:
|
if self._default is None:
|
||||||
self._default = _Default()
|
self._default = _Default()
|
||||||
@ -252,7 +243,7 @@ class XmlManifest(object):
|
|||||||
if self._projects.get(project.name):
|
if self._projects.get(project.name):
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
'duplicate project %s in %s' % \
|
'duplicate project %s in %s' % \
|
||||||
(project.name, self.manifestFile)
|
(project.name, self._manifestFile)
|
||||||
self._projects[project.name] = project
|
self._projects[project.name] = project
|
||||||
|
|
||||||
def _AddMetaProjectMirror(self, m):
|
def _AddMetaProjectMirror(self, m):
|
||||||
@ -324,7 +315,7 @@ class XmlManifest(object):
|
|||||||
if remote is None:
|
if remote is None:
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
"no remote for project %s within %s" % \
|
"no remote for project %s within %s" % \
|
||||||
(name, self.manifestFile)
|
(name, self._manifestFile)
|
||||||
|
|
||||||
revisionExpr = node.getAttribute('revision')
|
revisionExpr = node.getAttribute('revision')
|
||||||
if not revisionExpr:
|
if not revisionExpr:
|
||||||
@ -332,7 +323,7 @@ class XmlManifest(object):
|
|||||||
if not revisionExpr:
|
if not revisionExpr:
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
"no revision for project %s within %s" % \
|
"no revision for project %s within %s" % \
|
||||||
(name, self.manifestFile)
|
(name, self._manifestFile)
|
||||||
|
|
||||||
path = node.getAttribute('path')
|
path = node.getAttribute('path')
|
||||||
if not path:
|
if not path:
|
||||||
@ -340,7 +331,7 @@ class XmlManifest(object):
|
|||||||
if path.startswith('/'):
|
if path.startswith('/'):
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
"project %s path cannot be absolute in %s" % \
|
"project %s path cannot be absolute in %s" % \
|
||||||
(name, self.manifestFile)
|
(name, self._manifestFile)
|
||||||
|
|
||||||
if self.IsMirror:
|
if self.IsMirror:
|
||||||
relpath = None
|
relpath = None
|
||||||
@ -382,7 +373,7 @@ class XmlManifest(object):
|
|||||||
if not v:
|
if not v:
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
"remote %s not defined in %s" % \
|
"remote %s not defined in %s" % \
|
||||||
(name, self.manifestFile)
|
(name, self._manifestFile)
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def _reqatt(self, node, attname):
|
def _reqatt(self, node, attname):
|
||||||
@ -393,5 +384,5 @@ class XmlManifest(object):
|
|||||||
if not v:
|
if not v:
|
||||||
raise ManifestParseError, \
|
raise ManifestParseError, \
|
||||||
"no %s in <%s> within %s" % \
|
"no %s in <%s> within %s" % \
|
||||||
(attname, node.nodeName, self.manifestFile)
|
(attname, node.nodeName, self._manifestFile)
|
||||||
return v
|
return v
|
||||||
|
@ -163,6 +163,7 @@ See 'repo help --all' for a complete list of recognized commands.
|
|||||||
print >>sys.stderr, "repo: '%s' is not a repo command." % name
|
print >>sys.stderr, "repo: '%s' is not a repo command." % name
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
cmd.repodir = self.repodir
|
||||||
self._PrintCommandHelp(cmd)
|
self._PrintCommandHelp(cmd)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -214,7 +214,7 @@ uncommitted changes are present' % project.relpath
|
|||||||
if not syncbuf.Finish():
|
if not syncbuf.Finish():
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
self.manifest._Unload()
|
self.GetManifest(reparse=True)
|
||||||
all = self.GetProjects(args, missing_ok=True)
|
all = self.GetProjects(args, missing_ok=True)
|
||||||
missing = []
|
missing = []
|
||||||
for project in all:
|
for project in all:
|
||||||
|
Loading…
Reference in New Issue
Block a user