mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
Teach _LinkFile._Link to handle globs.
This allows a project to use globs in the linkfile src attribute. When a glob is used in the src the dest field must be a directory. Then _LinkFile._Link(self) calls will create symbolic links in the dest directory to all of the entries in the src as defined by the glob specification. Below all of the entries in master-configs/ will have symbolic links in <root dir>/configs directory: <project name="helloworld.git" path="apps/helloworld"> <linkfile src="master-configs/*" dest="configs"/> </project> Change-Id: Idfed8fa47c83d2ca6e2b8e867731b8e2f9e2eb47
This commit is contained in:
parent
472ce9f5fa
commit
4c426ef1d4
55
project.py
55
project.py
@ -16,6 +16,7 @@ from __future__ import print_function
|
|||||||
import contextlib
|
import contextlib
|
||||||
import errno
|
import errno
|
||||||
import filecmp
|
import filecmp
|
||||||
|
import glob
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
@ -233,28 +234,60 @@ class _CopyFile(object):
|
|||||||
_error('Cannot copy file %s to %s', src, dest)
|
_error('Cannot copy file %s to %s', src, dest)
|
||||||
|
|
||||||
class _LinkFile(object):
|
class _LinkFile(object):
|
||||||
def __init__(self, src, dest, relsrc, absdest):
|
def __init__(self, git_worktree, src, dest, relsrc, absdest):
|
||||||
|
self.git_worktree = git_worktree
|
||||||
self.src = src
|
self.src = src
|
||||||
self.dest = dest
|
self.dest = dest
|
||||||
self.src_rel_to_dest = relsrc
|
self.src_rel_to_dest = relsrc
|
||||||
self.abs_dest = absdest
|
self.abs_dest = absdest
|
||||||
|
|
||||||
def _Link(self):
|
def __linkIt(self, relSrc, absDest):
|
||||||
src = self.src_rel_to_dest
|
|
||||||
dest = self.abs_dest
|
|
||||||
# link file if it does not exist or is out of date
|
# link file if it does not exist or is out of date
|
||||||
if not os.path.islink(dest) or os.readlink(dest) != src:
|
if not os.path.islink(absDest) or (os.readlink(absDest) != relSrc):
|
||||||
try:
|
try:
|
||||||
# remove existing file first, since it might be read-only
|
# remove existing file first, since it might be read-only
|
||||||
if os.path.exists(dest):
|
if os.path.exists(absDest):
|
||||||
os.remove(dest)
|
os.remove(absDest)
|
||||||
else:
|
else:
|
||||||
dest_dir = os.path.dirname(dest)
|
dest_dir = os.path.dirname(absDest)
|
||||||
if not os.path.isdir(dest_dir):
|
if not os.path.isdir(dest_dir):
|
||||||
os.makedirs(dest_dir)
|
os.makedirs(dest_dir)
|
||||||
os.symlink(src, dest)
|
os.symlink(relSrc, absDest)
|
||||||
except IOError:
|
except IOError:
|
||||||
_error('Cannot link file %s to %s', src, dest)
|
_error('Cannot link file %s to %s', relSrc, absDest)
|
||||||
|
|
||||||
|
def _Link(self):
|
||||||
|
"""Link the self.rel_src_to_dest and self.abs_dest. Handles wild cards
|
||||||
|
on the src linking all of the files in the source in to the destination
|
||||||
|
directory.
|
||||||
|
"""
|
||||||
|
# We use the absSrc to handle the situation where the current directory
|
||||||
|
# is not the root of the repo
|
||||||
|
absSrc = os.path.join(self.git_worktree, self.src)
|
||||||
|
if os.path.exists(absSrc):
|
||||||
|
# Entity exists so just a simple one to one link operation
|
||||||
|
self.__linkIt(self.src_rel_to_dest, self.abs_dest)
|
||||||
|
else:
|
||||||
|
# Entity doesn't exist assume there is a wild card
|
||||||
|
absDestDir = self.abs_dest
|
||||||
|
if os.path.exists(absDestDir) and not os.path.isdir(absDestDir):
|
||||||
|
_error('Link error: src with wildcard, %s must be a directory',
|
||||||
|
absDestDir)
|
||||||
|
else:
|
||||||
|
absSrcFiles = glob.glob(absSrc)
|
||||||
|
for absSrcFile in absSrcFiles:
|
||||||
|
# Create a releative path from source dir to destination dir
|
||||||
|
absSrcDir = os.path.dirname(absSrcFile)
|
||||||
|
relSrcDir = os.path.relpath(absSrcDir, absDestDir)
|
||||||
|
|
||||||
|
# Get the source file name
|
||||||
|
srcFile = os.path.basename(absSrcFile)
|
||||||
|
|
||||||
|
# Now form the final full paths to srcFile. They will be
|
||||||
|
# absolute for the desintaiton and relative for the srouce.
|
||||||
|
absDest = os.path.join(absDestDir, srcFile)
|
||||||
|
relSrc = os.path.join(relSrcDir, srcFile)
|
||||||
|
self.__linkIt(relSrc, absDest)
|
||||||
|
|
||||||
class RemoteSpec(object):
|
class RemoteSpec(object):
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@ -1362,7 +1395,7 @@ class Project(object):
|
|||||||
# make src relative path to dest
|
# make src relative path to dest
|
||||||
absdestdir = os.path.dirname(absdest)
|
absdestdir = os.path.dirname(absdest)
|
||||||
relsrc = os.path.relpath(os.path.join(self.worktree, src), absdestdir)
|
relsrc = os.path.relpath(os.path.join(self.worktree, src), absdestdir)
|
||||||
self.linkfiles.append(_LinkFile(src, dest, relsrc, absdest))
|
self.linkfiles.append(_LinkFile(self.worktree, src, dest, relsrc, absdest))
|
||||||
|
|
||||||
def AddAnnotation(self, name, value, keep):
|
def AddAnnotation(self, name, value, keep):
|
||||||
self.annotations.append(_Annotation(name, value, keep))
|
self.annotations.append(_Annotation(name, value, keep))
|
||||||
|
Loading…
Reference in New Issue
Block a user