Skip to content

Instantly share code, notes, and snippets.

@pfn
Last active December 23, 2015 07:09
Show Gist options
  • Save pfn/6599272 to your computer and use it in GitHub Desktop.
Save pfn/6599272 to your computer and use it in GitHub Desktop.
cheap repo hack for windows
#!/usr/bin/python
from optparse import OptionParser
import sys
import os
from subprocess import Popen
from subprocess import PIPE
import urllib
from xml.parsers import expat
manifest = "https://android.googlesource.com/platform/manifest"
parser = OptionParser()
parser.usage = parser.usage + " <command>"
parser.prog = "repo.py"
commandsHelp = """
Available commands:
init <dest> - clone aosp manifest from repo server
sync - pull from repo server
grep <term> - grep from all repos
"""
(options, args) = parser.parse_args()
def usage():
parser.print_help(sys.stderr)
print(commandsHelp)
sys.exit(1)
if not args:
usage()
class Project:
name = None
path = None
fetch = None
groups = []
def __str__(self):
return "%s@%s:[%s]" % (self.name, self.path, str(self.groups))
class Repo:
base = None
fetch = None
projects = []
def __str__(self):
return "repo: " + str(self.projects)
def parseManifest(path="."):
while not os.path.exists(path + "/.manifest/default.xml"):
lastpath = path
path = os.path.dirname(os.path.abspath(path))
if path == lastpath:
print("manifest not found")
sys.exit(1)
repo = Repo()
repo.base = os.path.abspath(path)
def elem(name, attrs):
if name == "remote":
repo.fetch = attrs['fetch']
if name == "project":
project = Project()
project.path = attrs['path']
project.name = attrs['name']
project.fetch = urllib.basejoin(manifest, "..")
project.fetch = urllib.basejoin(project.fetch, project.name)
if 'groups' in attrs:
project.groups = attrs['groups'].split(',')
repo.projects.append(project)
parser = expat.ParserCreate()
parser.StartElementHandler = elem
parser.ParseFile(file(path + "/.manifest/default.xml"))
f = lambda x: "notdefault" not in x.groups or "tools" in x.groups
repo.projects = filter(f, repo.projects)
return repo
def clone(args):
if not args:
usage()
dest = args[0] + "/.manifest"
os.makedirs(dest, mode=0755)
os.system("git clone %s \"%s\"" % (manifest, dest))
repo = parseManifest()
def grep(args):
if not args:
usage()
repo = parseManifest()
less = Popen("less -", stdout=sys.stdout, stdin=PIPE)
for project in repo.projects:
dest = os.path.normpath(repo.base + os.sep + project.path)
os.chdir(dest)
print >>less.stdin, "Results in %s" % project.path
gitgrep = Popen("git --no-pager grep --color %s" %
" ".join(args), stdout=less.stdin)
gitgrep.communicate()
result = gitgrep.wait()
if result and result == 128: break
def pull(args):
repo = parseManifest()
projects = len(repo.projects)
for (i, project) in zip(xrange(1, projects + 1), repo.projects):
dest = os.path.normpath(repo.base + os.sep + project.path)
if not os.path.exists(dest):
os.makedirs(dest)
os.system("git clone %s \"%s\"" % (project.fetch, dest))
else:
os.chdir(dest)
print("Updating %d/%d %s" % (i, projects, project.path))
os.system("git pull")
commands = {
"init": clone,
"sync": pull,
"grep": grep,
}
if args[0] not in commands:
usage()
commands[args[0]](args[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment