Commit 13508fdb by Matthias Putz

Update: google git-repo v1.12.32

parent 12c1beb7
...@@ -231,7 +231,12 @@ class MirrorSafeCommand(object): ...@@ -231,7 +231,12 @@ class MirrorSafeCommand(object):
and does not require a working directory. and does not require a working directory.
""" """
class RequiresGitcCommand(object): class GitcAvailableCommand(object):
"""Command that requires GITC to be available, but does """Command that requires GITC to be available, but does
not require the local client to be a GITC client. not require the local client to be a GITC client.
""" """
class GitcClientCommand(object):
"""Command that requires the local client to be a GITC
client.
"""
...@@ -50,7 +50,9 @@ following DTD: ...@@ -50,7 +50,9 @@ following DTD:
<!ATTLIST url CDATA #REQUIRED> <!ATTLIST url CDATA #REQUIRED>
<!ELEMENT project (annotation*, <!ELEMENT project (annotation*,
project*)> project*,
copyfile?,
linkfile?)>
<!ATTLIST project name CDATA #REQUIRED> <!ATTLIST project name CDATA #REQUIRED>
<!ATTLIST project path CDATA #IMPLIED> <!ATTLIST project path CDATA #IMPLIED>
<!ATTLIST project remote IDREF #IMPLIED> <!ATTLIST project remote IDREF #IMPLIED>
...@@ -68,6 +70,14 @@ following DTD: ...@@ -68,6 +70,14 @@ following DTD:
<!ATTLIST annotation value CDATA #REQUIRED> <!ATTLIST annotation value CDATA #REQUIRED>
<!ATTLIST annotation keep CDATA "true"> <!ATTLIST annotation keep CDATA "true">
<!ELEMENT copyfile (EMPTY)>
<!ATTLIST src value CDATA #REQUIRED>
<!ATTLIST dest value CDATA #REQUIRED>
<!ELEMENT linkfile (EMPTY)>
<!ATTLIST src value CDATA #REQUIRED>
<!ATTLIST dest value CDATA #REQUIRED>
<!ELEMENT extend-project> <!ELEMENT extend-project>
<!ATTLIST extend-project name CDATA #REQUIRED> <!ATTLIST extend-project name CDATA #REQUIRED>
<!ATTLIST extend-project path CDATA #IMPLIED> <!ATTLIST extend-project path CDATA #IMPLIED>
...@@ -285,6 +295,21 @@ prefixed with REPO__. In addition, there is an optional attribute ...@@ -285,6 +295,21 @@ prefixed with REPO__. In addition, there is an optional attribute
"false". This attribute determines whether or not the annotation will "false". This attribute determines whether or not the annotation will
be kept when exported with the manifest subcommand. be kept when exported with the manifest subcommand.
Element copyfile
----------------
Zero or more copyfile elements may be specified as children of a
project element. Each element describes a src-dest pair of files;
the "src" file will be copied to the "dest" place during 'repo sync'
command.
"src" is project relative, "dest" is relative to the top of the tree.
Element linkfile
----------------
It's just like copyfile and runs at the same time as copyfile but
instead of copying it creates a symlink.
Element remove-project Element remove-project
---------------------- ----------------------
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
from __future__ import print_function from __future__ import print_function
import os import os
import platform
import re
import sys import sys
import time import time
...@@ -22,24 +24,13 @@ import git_command ...@@ -22,24 +24,13 @@ import git_command
import git_config import git_config
import wrapper import wrapper
GITC_FS_ROOT_DIR = '/gitc/manifest-rw/'
NUM_BATCH_RETRIEVE_REVISIONID = 300 NUM_BATCH_RETRIEVE_REVISIONID = 300
def get_gitc_manifest_dir(): def get_gitc_manifest_dir():
return wrapper.Wrapper().get_gitc_manifest_dir() return wrapper.Wrapper().get_gitc_manifest_dir()
def parse_clientdir(gitc_fs_path): def parse_clientdir(gitc_fs_path):
"""Parse a path in the GITC FS and return its client name. return wrapper.Wrapper().gitc_parse_clientdir(gitc_fs_path)
@param gitc_fs_path: A subdirectory path within the GITC_FS_ROOT_DIR.
@returns: The GITC client name
"""
if (gitc_fs_path == GITC_FS_ROOT_DIR or
not gitc_fs_path.startswith(GITC_FS_ROOT_DIR)):
return None
return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0]
def _set_project_revisions(projects): def _set_project_revisions(projects):
"""Sets the revisionExpr for a list of projects. """Sets the revisionExpr for a list of projects.
...@@ -65,26 +56,82 @@ def _set_project_revisions(projects): ...@@ -65,26 +56,82 @@ def _set_project_revisions(projects):
sys.exit(1) sys.exit(1)
proj.revisionExpr = gitcmd.stdout.split('\t')[0] proj.revisionExpr = gitcmd.stdout.split('\t')[0]
def generate_gitc_manifest(client_dir, manifest, projects=None): def _manifest_groups(manifest):
"""Returns the manifest group string that should be synced
This is the same logic used by Command.GetProjects(), which is used during
repo sync
@param manifest: The XmlManifest object
"""
mp = manifest.manifestProject
groups = mp.config.GetString('manifest.groups')
if not groups:
groups = 'default,platform-' + platform.system().lower()
return groups
def generate_gitc_manifest(gitc_manifest, manifest, paths=None):
"""Generate a manifest for shafsd to use for this GITC client. """Generate a manifest for shafsd to use for this GITC client.
@param client_dir: GITC client directory to install the .manifest file in. @param gitc_manifest: Current gitc manifest, or None if there isn't one yet.
@param manifest: XmlManifest object representing the repo manifest. @param manifest: A GitcManifest object loaded with the current repo manifest.
@param projects: List of projects we want to update, this must be a sublist @param paths: List of project paths we want to update.
of manifest.projects to work properly. If not provided,
manifest.projects is used.
""" """
print('Generating GITC Manifest by fetching revision SHAs for each ' print('Generating GITC Manifest by fetching revision SHAs for each '
'project.') 'project.')
if projects is None: if paths is None:
projects = manifest.projects paths = manifest.paths.keys()
groups = [x for x in re.split(r'[,\s]+', _manifest_groups(manifest)) if x]
# Convert the paths to projects, and filter them to the matched groups.
projects = [manifest.paths[p] for p in paths]
projects = [p for p in projects if p.MatchesGroups(groups)]
if gitc_manifest is not None:
for path, proj in manifest.paths.iteritems():
if not proj.MatchesGroups(groups):
continue
if not proj.upstream and not git_config.IsId(proj.revisionExpr):
proj.upstream = proj.revisionExpr
if not path in gitc_manifest.paths:
# Any new projects need their first revision, even if we weren't asked
# for them.
projects.append(proj)
elif not path in paths:
# And copy revisions from the previous manifest if we're not updating
# them now.
gitc_proj = gitc_manifest.paths[path]
if gitc_proj.old_revision:
proj.revisionExpr = None
proj.old_revision = gitc_proj.old_revision
else:
proj.revisionExpr = gitc_proj.revisionExpr
index = 0 index = 0
while index < len(projects): while index < len(projects):
_set_project_revisions( _set_project_revisions(
projects[index:(index+NUM_BATCH_RETRIEVE_REVISIONID)]) projects[index:(index+NUM_BATCH_RETRIEVE_REVISIONID)])
index += NUM_BATCH_RETRIEVE_REVISIONID index += NUM_BATCH_RETRIEVE_REVISIONID
if gitc_manifest is not None:
for path, proj in gitc_manifest.paths.iteritems():
if proj.old_revision and path in paths:
# If we updated a project that has been started, keep the old-revision
# updated.
repo_proj = manifest.paths[path]
repo_proj.old_revision = repo_proj.revisionExpr
repo_proj.revisionExpr = None
# Convert URLs from relative to absolute.
for name, remote in manifest.remotes.iteritems():
remote.fetchUrl = remote.resolvedFetchUrl
# Save the manifest. # Save the manifest.
save_manifest(manifest, client_dir=client_dir) save_manifest(manifest)
def save_manifest(manifest, client_dir=None): def save_manifest(manifest, client_dir=None):
"""Save the manifest file in the client_dir. """Save the manifest file in the client_dir.
...@@ -95,7 +142,7 @@ def save_manifest(manifest, client_dir=None): ...@@ -95,7 +142,7 @@ def save_manifest(manifest, client_dir=None):
if not client_dir: if not client_dir:
client_dir = manifest.gitc_client_dir client_dir = manifest.gitc_client_dir
with open(os.path.join(client_dir, '.manifest'), 'w') as f: with open(os.path.join(client_dir, '.manifest'), 'w') as f:
manifest.Save(f) manifest.Save(f, groups=_manifest_groups(manifest))
# TODO(sbasi/jorg): Come up with a solution to remove the sleep below. # TODO(sbasi/jorg): Come up with a solution to remove the sleep below.
# Give the GITC filesystem time to register the manifest changes. # Give the GITC filesystem time to register the manifest changes.
time.sleep(3) time.sleep(3)
\ No newline at end of file
...@@ -44,7 +44,7 @@ from git_command import git, GitCommand ...@@ -44,7 +44,7 @@ from git_command import git, GitCommand
from git_config import init_ssh, close_ssh from git_config import init_ssh, close_ssh
from command import InteractiveCommand from command import InteractiveCommand
from command import MirrorSafeCommand from command import MirrorSafeCommand
from command import RequiresGitcCommand from command import GitcAvailableCommand, GitcClientCommand
from subcmds.version import Version from subcmds.version import Version
from editor import Editor from editor import Editor
from error import DownloadError from error import DownloadError
...@@ -146,11 +146,16 @@ class _Repo(object): ...@@ -146,11 +146,16 @@ class _Repo(object):
file=sys.stderr) file=sys.stderr)
return 1 return 1
if isinstance(cmd, RequiresGitcCommand) and not gitc_utils.get_gitc_manifest_dir(): if isinstance(cmd, GitcAvailableCommand) and not gitc_utils.get_gitc_manifest_dir():
print("fatal: '%s' requires GITC to be available" % name, print("fatal: '%s' requires GITC to be available" % name,
file=sys.stderr) file=sys.stderr)
return 1 return 1
if isinstance(cmd, GitcClientCommand) and not gitc_client_name:
print("fatal: '%s' requires a GITC client" % name,
file=sys.stderr)
return 1
try: try:
copts, cargs = cmd.OptionParser.parse_args(argv) copts, cargs = cmd.OptionParser.parse_args(argv)
copts = cmd.ReadEnvironmentOptions(copts) copts = cmd.ReadEnvironmentOptions(copts)
......
...@@ -169,12 +169,13 @@ class XmlManifest(object): ...@@ -169,12 +169,13 @@ class XmlManifest(object):
def _ParseGroups(self, groups): def _ParseGroups(self, groups):
return [x for x in re.split(r'[,\s]+', groups) if x] return [x for x in re.split(r'[,\s]+', groups) if x]
def Save(self, fd, peg_rev=False, peg_rev_upstream=True): def Save(self, fd, peg_rev=False, peg_rev_upstream=True, groups=None):
"""Write the current manifest out to the given file descriptor. """Write the current manifest out to the given file descriptor.
""" """
mp = self.manifestProject mp = self.manifestProject
groups = mp.config.GetString('manifest.groups') if groups is None:
groups = mp.config.GetString('manifest.groups')
if groups: if groups:
groups = self._ParseGroups(groups) groups = self._ParseGroups(groups)
......
...@@ -21,7 +21,7 @@ REPO_REV = 'stable' ...@@ -21,7 +21,7 @@ REPO_REV = 'stable'
# limitations under the License. # limitations under the License.
# increment this whenever we make important changes to this script # increment this whenever we make important changes to this script
VERSION = (1, 21) VERSION = (1, 22)
# increment this if the MAINTAINER_KEYS block is modified # increment this if the MAINTAINER_KEYS block is modified
KEYRING_VERSION = (1, 2) KEYRING_VERSION = (1, 2)
...@@ -68,6 +68,7 @@ S_manifests = 'manifests' # special manifest repository ...@@ -68,6 +68,7 @@ S_manifests = 'manifests' # special manifest repository
REPO_MAIN = S_repo + '/main.py' # main script REPO_MAIN = S_repo + '/main.py' # main script
MIN_PYTHON_VERSION = (2, 6) # minimum supported python version MIN_PYTHON_VERSION = (2, 6) # minimum supported python version
GITC_CONFIG_FILE = '/gitc/.config' GITC_CONFIG_FILE = '/gitc/.config'
GITC_FS_ROOT_DIR = '/gitc/manifest-rw/'
import errno import errno
...@@ -180,7 +181,7 @@ def _GitcInitOptions(init_optparse): ...@@ -180,7 +181,7 @@ def _GitcInitOptions(init_optparse):
help='Optional manifest file to use for this GITC client.') help='Optional manifest file to use for this GITC client.')
g.add_option('-c', '--gitc-client', g.add_option('-c', '--gitc-client',
dest='gitc_client', dest='gitc_client',
help='The name for the new gitc_client instance.') help='The name of the gitc_client instance to create or modify.')
_gitc_manifest_dir = None _gitc_manifest_dir = None
def get_gitc_manifest_dir(): def get_gitc_manifest_dir():
...@@ -197,6 +198,28 @@ def get_gitc_manifest_dir(): ...@@ -197,6 +198,28 @@ def get_gitc_manifest_dir():
pass pass
return _gitc_manifest_dir return _gitc_manifest_dir
def gitc_parse_clientdir(gitc_fs_path):
"""Parse a path in the GITC FS and return its client name.
@param gitc_fs_path: A subdirectory path within the GITC_FS_ROOT_DIR.
@returns: The GITC client name
"""
if gitc_fs_path == GITC_FS_ROOT_DIR:
return None
if not gitc_fs_path.startswith(GITC_FS_ROOT_DIR):
manifest_dir = get_gitc_manifest_dir()
if manifest_dir == '':
return None
if manifest_dir[-1] != '/':
manifest_dir += '/'
if gitc_fs_path == manifest_dir:
return None
if not gitc_fs_path.startswith(manifest_dir):
return None
return gitc_fs_path.split(manifest_dir)[1].split('/')[0]
return gitc_fs_path.split(GITC_FS_ROOT_DIR)[1].split('/')[0]
class CloneFailure(Exception): class CloneFailure(Exception):
"""Indicate the remote clone of repo itself failed. """Indicate the remote clone of repo itself failed.
""" """
...@@ -235,10 +258,13 @@ def _Init(args, gitc_init=False): ...@@ -235,10 +258,13 @@ def _Init(args, gitc_init=False):
_print('fatal: GITC filesystem is not available. Exiting...', _print('fatal: GITC filesystem is not available. Exiting...',
file=sys.stderr) file=sys.stderr)
sys.exit(1) sys.exit(1)
if not opt.gitc_client: gitc_client = opt.gitc_client
if not gitc_client:
gitc_client = gitc_parse_clientdir(os.getcwd())
if not gitc_client:
_print('fatal: GITC client (-c) is required.', file=sys.stderr) _print('fatal: GITC client (-c) is required.', file=sys.stderr)
sys.exit(1) sys.exit(1)
client_dir = os.path.join(gitc_manifest_dir, opt.gitc_client) client_dir = os.path.join(gitc_manifest_dir, gitc_client)
if not os.path.exists(client_dir): if not os.path.exists(client_dir):
os.makedirs(client_dir) os.makedirs(client_dir)
os.chdir(client_dir) os.chdir(client_dir)
...@@ -526,8 +552,7 @@ def _Clone(url, local, quiet): ...@@ -526,8 +552,7 @@ def _Clone(url, local, quiet):
'+refs/heads/*:refs/remotes/origin/*') '+refs/heads/*:refs/remotes/origin/*')
if _DownloadBundle(url, local, quiet): if _DownloadBundle(url, local, quiet):
_ImportBundle(local) _ImportBundle(local)
else: _Fetch(url, local, 'origin', quiet)
_Fetch(url, local, 'origin', quiet)
def _Verify(cwd, branch, quiet): def _Verify(cwd, branch, quiet):
...@@ -732,9 +757,13 @@ def _SetDefaultsTo(gitdir): ...@@ -732,9 +757,13 @@ def _SetDefaultsTo(gitdir):
def main(orig_args): def main(orig_args):
repo_main, rel_repo_dir = _FindRepo()
cmd, opt, args = _ParseArguments(orig_args) cmd, opt, args = _ParseArguments(orig_args)
repo_main, rel_repo_dir = None, None
# Don't use the local repo copy, make sure to switch to the gitc client first.
if cmd != 'gitc-init':
repo_main, rel_repo_dir = _FindRepo()
wrapper_path = os.path.abspath(__file__) wrapper_path = os.path.abspath(__file__)
my_main, my_git = _RunSelf(wrapper_path) my_main, my_git = _RunSelf(wrapper_path)
......
#
# Copyright (C) 2015 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 __future__ import print_function
import os
import shutil
import sys
from command import Command, GitcClientCommand
import gitc_utils
from pyversion import is_python3
if not is_python3():
# pylint:disable=W0622
input = raw_input
# pylint:enable=W0622
class GitcDelete(Command, GitcClientCommand):
common = True
visible_everywhere = False
helpSummary = "Delete a GITC Client."
helpUsage = """
%prog
"""
helpDescription = """
This subcommand deletes the current GITC client, deleting the GITC manifest
and all locally downloaded sources.
"""
def _Options(self, p):
p.add_option('-f', '--force',
dest='force', action='store_true',
help='Force the deletion (no prompt).')
def Execute(self, opt, args):
if not opt.force:
prompt = ('This will delete GITC client: %s\nAre you sure? (yes/no) ' %
self.gitc_manifest.gitc_client_name)
response = input(prompt).lower()
if not response == 'yes':
print('Response was not "yes"\n Exiting...')
sys.exit(1)
shutil.rmtree(self.gitc_manifest.gitc_client_dir)
...@@ -18,11 +18,13 @@ import os ...@@ -18,11 +18,13 @@ import os
import sys import sys
import gitc_utils import gitc_utils
from command import RequiresGitcCommand from command import GitcAvailableCommand
from manifest_xml import GitcManifest
from subcmds import init from subcmds import init
import wrapper
class GitcInit(init.Init, RequiresGitcCommand): class GitcInit(init.Init, GitcAvailableCommand):
common = True common = True
helpSummary = "Initialize a GITC Client." helpSummary = "Initialize a GITC Client."
helpUsage = """ helpUsage = """
...@@ -34,7 +36,7 @@ with the GITC file system. ...@@ -34,7 +36,7 @@ with the GITC file system.
This command will setup the client directory, initialize repo, just This command will setup the client directory, initialize repo, just
like repo init does, and then downloads the manifest collection like repo init does, and then downloads the manifest collection
and installs in in the .repo/directory of the GITC client. and installs it in the .repo/directory of the GITC client.
Once this is done, a GITC manifest is generated by pulling the HEAD Once this is done, a GITC manifest is generated by pulling the HEAD
SHA for each project and generates the properly formatted XML file SHA for each project and generates the properly formatted XML file
...@@ -54,29 +56,27 @@ use for this GITC client. ...@@ -54,29 +56,27 @@ use for this GITC client.
help='Optional manifest file to use for this GITC client.') help='Optional manifest file to use for this GITC client.')
g.add_option('-c', '--gitc-client', g.add_option('-c', '--gitc-client',
dest='gitc_client', dest='gitc_client',
help='The name for the new gitc_client instance.') help='The name of the gitc_client instance to create or modify.')
def Execute(self, opt, args): def Execute(self, opt, args):
if not opt.gitc_client: gitc_client = gitc_utils.parse_clientdir(os.getcwd())
print('fatal: gitc client (-c) is required', file=sys.stderr) if not gitc_client or (opt.gitc_client and gitc_client != opt.gitc_client):
print('fatal: Please update your repo command. See go/gitc for instructions.', file=sys.stderr)
sys.exit(1) sys.exit(1)
self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(), self.client_dir = os.path.join(gitc_utils.get_gitc_manifest_dir(),
opt.gitc_client) gitc_client)
if not os.path.exists(gitc_utils.get_gitc_manifest_dir()):
os.makedirs(gitc_utils.get_gitc_manifest_dir())
if not os.path.exists(self.client_dir):
os.mkdir(self.client_dir)
super(GitcInit, self).Execute(opt, args) super(GitcInit, self).Execute(opt, args)
for name, remote in self.manifest.remotes.iteritems(): manifest_file = self.manifest.manifestFile
remote.fetchUrl = remote.resolvedFetchUrl
if opt.manifest_file: if opt.manifest_file:
if not os.path.exists(opt.manifest_file): if not os.path.exists(opt.manifest_file):
print('fatal: Specified manifest file %s does not exist.' % print('fatal: Specified manifest file %s does not exist.' %
opt.manifest_file) opt.manifest_file)
sys.exit(1) sys.exit(1)
self.manifest.Override(opt.manifest_file) manifest_file = opt.manifest_file
gitc_utils.generate_gitc_manifest(self.client_dir, self.manifest)
manifest = GitcManifest(self.repodir, gitc_client)
manifest.Override(manifest_file)
gitc_utils.generate_gitc_manifest(None, manifest)
print('Please run `cd %s` to view your GITC client.' % print('Please run `cd %s` to view your GITC client.' %
os.path.join(gitc_utils.GITC_FS_ROOT_DIR, opt.gitc_client)) os.path.join(wrapper.Wrapper().GITC_FS_ROOT_DIR, gitc_client))
...@@ -19,7 +19,7 @@ import sys ...@@ -19,7 +19,7 @@ import sys
from formatter import AbstractFormatter, DumbWriter from formatter import AbstractFormatter, DumbWriter
from color import Coloring from color import Coloring
from command import PagedCommand, MirrorSafeCommand, RequiresGitcCommand from command import PagedCommand, MirrorSafeCommand, GitcAvailableCommand, GitcClientCommand
import gitc_utils import gitc_utils
class Help(PagedCommand, MirrorSafeCommand): class Help(PagedCommand, MirrorSafeCommand):
...@@ -57,8 +57,12 @@ Displays detailed usage information about a command. ...@@ -57,8 +57,12 @@ Displays detailed usage information about a command.
print('The most commonly used repo commands are:') print('The most commonly used repo commands are:')
def gitc_supported(cmd): def gitc_supported(cmd):
if not isinstance(cmd, RequiresGitcCommand): if not isinstance(cmd, GitcAvailableCommand) and not isinstance(cmd, GitcClientCommand):
return True return True
if self.manifest.isGitcClient:
return True
if isinstance(cmd, GitcClientCommand):
return False
if gitc_utils.get_gitc_manifest_dir(): if gitc_utils.get_gitc_manifest_dir():
return True return True
return False return False
......
...@@ -57,7 +57,6 @@ revision specified in the manifest. ...@@ -57,7 +57,6 @@ revision specified in the manifest.
print("error: at least one project must be specified", file=sys.stderr) print("error: at least one project must be specified", file=sys.stderr)
sys.exit(1) sys.exit(1)
proj_name_to_gitc_proj_dict = {}
if self.gitc_manifest: if self.gitc_manifest:
all_projects = self.GetProjects(projects, manifest=self.gitc_manifest, all_projects = self.GetProjects(projects, manifest=self.gitc_manifest,
missing_ok=True) missing_ok=True)
...@@ -67,7 +66,6 @@ revision specified in the manifest. ...@@ -67,7 +66,6 @@ revision specified in the manifest.
else: else:
project.already_synced = False project.already_synced = False
project.old_revision = project.revisionExpr project.old_revision = project.revisionExpr
proj_name_to_gitc_proj_dict[project.name] = project
project.revisionExpr = None project.revisionExpr = None
# Save the GITC manifest. # Save the GITC manifest.
gitc_utils.save_manifest(self.gitc_manifest) gitc_utils.save_manifest(self.gitc_manifest)
...@@ -77,9 +75,10 @@ revision specified in the manifest. ...@@ -77,9 +75,10 @@ revision specified in the manifest.
pm = Progress('Starting %s' % nb, len(all_projects)) pm = Progress('Starting %s' % nb, len(all_projects))
for project in all_projects: for project in all_projects:
pm.update() pm.update()
if self.gitc_manifest: if self.gitc_manifest:
gitc_project = proj_name_to_gitc_proj_dict[project.name] gitc_project = self.gitc_manifest.paths[project.relpath]
# Sync projects that have already been opened. # Sync projects that have not been opened.
if not gitc_project.already_synced: if not gitc_project.already_synced:
proj_localdir = os.path.join(self.gitc_manifest.gitc_client_dir, proj_localdir = os.path.join(self.gitc_manifest.gitc_client_dir,
project.relpath) project.relpath)
...@@ -89,7 +88,7 @@ revision specified in the manifest. ...@@ -89,7 +88,7 @@ revision specified in the manifest.
project.Sync_NetworkHalf() project.Sync_NetworkHalf()
sync_buf = SyncBuffer(self.manifest.manifestProject.config) sync_buf = SyncBuffer(self.manifest.manifestProject.config)
project.Sync_LocalHalf(sync_buf) project.Sync_LocalHalf(sync_buf)
project.revisionExpr = gitc_project.old_revision project.revisionId = gitc_project.old_revision
# If the current revision is a specific SHA1 then we can't push back # If the current revision is a specific SHA1 then we can't push back
# to it; so substitute with dest_branch if defined, or with manifest # to it; so substitute with dest_branch if defined, or with manifest
...@@ -100,6 +99,7 @@ revision specified in the manifest. ...@@ -100,6 +99,7 @@ revision specified in the manifest.
branch_merge = project.dest_branch branch_merge = project.dest_branch
else: else:
branch_merge = self.manifest.default.revisionExpr branch_merge = self.manifest.default.revisionExpr
if not project.StartBranch(nb, branch_merge=branch_merge): if not project.StartBranch(nb, branch_merge=branch_merge):
err.append(project) err.append(project)
pm.end() pm.end()
......
...@@ -75,6 +75,7 @@ from error import RepoChangedException, GitError, ManifestParseError ...@@ -75,6 +75,7 @@ from error import RepoChangedException, GitError, ManifestParseError
from project import SyncBuffer from project import SyncBuffer
from progress import Progress from progress import Progress
from wrapper import Wrapper from wrapper import Wrapper
from manifest_xml import GitcManifest
_ONE_DAY_S = 24 * 60 * 60 _ONE_DAY_S = 24 * 60 * 60
...@@ -670,32 +671,39 @@ later is required to fix a server side protocol bug. ...@@ -670,32 +671,39 @@ later is required to fix a server side protocol bug.
if opt.jobs is None: if opt.jobs is None:
self.jobs = self.manifest.default.sync_j self.jobs = self.manifest.default.sync_j
# TODO (sbasi) - Add support for manifest changes, aka projects
# have been added or deleted from the manifest.
if self.gitc_manifest: if self.gitc_manifest:
gitc_manifest_projects = self.GetProjects(args, gitc_manifest_projects = self.GetProjects(args,
manifest=self.gitc_manifest,
missing_ok=True) missing_ok=True)
gitc_projects = [] gitc_projects = []
opened_projects = [] opened_projects = []
for project in gitc_manifest_projects: for project in gitc_manifest_projects:
if not project.old_revision: if project.relpath in self.gitc_manifest.paths and \
gitc_projects.append(project) self.gitc_manifest.paths[project.relpath].old_revision:
opened_projects.append(project.relpath)
else: else:
opened_projects.append(project) gitc_projects.append(project.relpath)
if gitc_projects and not opt.local_only: if not args:
gitc_projects = None
if gitc_projects != [] and not opt.local_only:
print('Updating GITC client: %s' % self.gitc_manifest.gitc_client_name) print('Updating GITC client: %s' % self.gitc_manifest.gitc_client_name)
gitc_utils.generate_gitc_manifest(self.gitc_manifest.gitc_client_dir, manifest = GitcManifest(self.repodir, self.gitc_manifest.gitc_client_name)
self.gitc_manifest, if manifest_name:
manifest.Override(manifest_name)
else:
manifest.Override(self.manifest.manifestFile)
gitc_utils.generate_gitc_manifest(self.gitc_manifest,
manifest,
gitc_projects) gitc_projects)
print('GITC client successfully synced.') print('GITC client successfully synced.')
# The opened projects need to be synced as normal, therefore we # The opened projects need to be synced as normal, therefore we
# generate a new args list to represent the opened projects. # generate a new args list to represent the opened projects.
args = [] # TODO: make this more reliable -- if there's a project name/path overlap,
for proj in opened_projects: # this may choose the wrong project.
args.append(os.path.relpath(proj.worktree, os.getcwd())) args = [os.path.relpath(self.manifest.paths[p].worktree, os.getcwd())
for p in opened_projects]
if not args: if not args:
return return
all_projects = self.GetProjects(args, all_projects = self.GetProjects(args,
...@@ -908,6 +916,7 @@ class PersistentTransport(xmlrpc.client.Transport): ...@@ -908,6 +916,7 @@ class PersistentTransport(xmlrpc.client.Transport):
# stripping those prefixes away. # stripping those prefixes away.
if cookiefile: if cookiefile:
tmpcookiefile = tempfile.NamedTemporaryFile() tmpcookiefile = tempfile.NamedTemporaryFile()
tmpcookiefile.write("# HTTP Cookie File")
try: try:
with open(cookiefile) as f: with open(cookiefile) as f:
for line in f: for line in f:
...@@ -917,7 +926,10 @@ class PersistentTransport(xmlrpc.client.Transport): ...@@ -917,7 +926,10 @@ class PersistentTransport(xmlrpc.client.Transport):
tmpcookiefile.flush() tmpcookiefile.flush()
cookiejar = cookielib.MozillaCookieJar(tmpcookiefile.name) cookiejar = cookielib.MozillaCookieJar(tmpcookiefile.name)
cookiejar.load() try:
cookiejar.load()
except cookielib.LoadError:
cookiejar = cookielib.CookieJar()
finally: finally:
tmpcookiefile.close() tmpcookiefile.close()
else: else:
......
gitc_dir=/test/usr/local/google/gitc
#
# Copyright (C) 2015 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
import unittest
import wrapper
def fixture(*paths):
"""Return a path relative to tests/fixtures.
"""
return os.path.join(os.path.dirname(__file__), 'fixtures', *paths)
class RepoWrapperUnitTest(unittest.TestCase):
"""Tests helper functions in the repo wrapper
"""
def setUp(self):
"""Load the wrapper module every time
"""
wrapper._wrapper_module = None
self.wrapper = wrapper.Wrapper()
def test_get_gitc_manifest_dir_no_gitc(self):
"""
Test reading a missing gitc config file
"""
self.wrapper.GITC_CONFIG_FILE = fixture('missing_gitc_config')
val = self.wrapper.get_gitc_manifest_dir()
self.assertEqual(val, '')
def test_get_gitc_manifest_dir(self):
"""
Test reading the gitc config file and parsing the directory
"""
self.wrapper.GITC_CONFIG_FILE = fixture('gitc_config')
val = self.wrapper.get_gitc_manifest_dir()
self.assertEqual(val, '/test/usr/local/google/gitc')
def test_gitc_parse_clientdir_no_gitc(self):
"""
Test parsing the gitc clientdir without gitc running
"""
self.wrapper.GITC_CONFIG_FILE = fixture('missing_gitc_config')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/something'), None)
self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test'), 'test')
def test_gitc_parse_clientdir(self):
"""
Test parsing the gitc clientdir
"""
self.wrapper.GITC_CONFIG_FILE = fixture('gitc_config')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/something'), None)
self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test'), 'test')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test/'), 'test')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/test/extra'), 'test')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test'), 'test')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test/'), 'test')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/test/extra'), 'test')
self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/'), None)
self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/'), None)
if __name__ == '__main__':
unittest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment