fgmeta/maintain_catalog.py

227 lines
6.7 KiB
Python
Raw Permalink Normal View History

2015-06-05 05:09:46 +08:00
#!/usr/bin/python
2015-07-30 02:54:45 +08:00
import os, sys, re, glob, shutil
2015-06-05 05:09:46 +08:00
import subprocess
import sgprops
2015-07-23 11:35:57 +08:00
import argparse
import urllib2
2015-07-26 11:45:01 +08:00
import package as pkg
2015-06-05 05:09:46 +08:00
import svn_catalog_repository
import git_catalog_repository
import git_discrete_repository
2015-07-23 11:35:57 +08:00
parser = argparse.ArgumentParser()
parser.add_argument("--clean", help="Regenerate every package",
action="store_true")
parser.add_argument("--update", help="Update/pull SCM source",
action="store_true")
parser.add_argument("--force-dirty", dest="forcedirty",
help="Mark every package as dirty", action="store_true")
2015-07-28 11:39:32 +08:00
parser.add_argument("--no-update",
dest = "noupdate",
help="Disable updating from SCM source",
2015-07-28 10:45:55 +08:00
action="store_true")
parser.add_argument("--no-upload",
dest = "noupload",
help="Disable uploading to destination server",
action="store_true")
2015-07-23 11:35:57 +08:00
parser.add_argument("dir", help="Catalog directory")
args = parser.parse_args()
2015-09-28 12:15:44 +08:00
CATALOG_VERSION = 4
includePaths = []
2015-09-25 08:45:42 +08:00
packages = {}
2015-07-15 10:37:39 +08:00
def scanPackages(scmRepo):
2015-06-05 05:09:46 +08:00
result = []
globPath = scmRepo.aircraftPath
if globPath is None:
return result
print "Scanning", globPath
print os.getcwd()
for d in glob.glob(globPath):
# check dir contains at least one -set.xml file
if len(glob.glob(os.path.join(d, "*-set.xml"))) == 0:
print "no -set.xml in", d
continue
result.append(pkg.PackageData(d, scmRepo))
2015-06-05 05:09:46 +08:00
return result
def initScmRepository(node):
scmType = node.getValue("type")
if (scmType == "svn"):
return svn_catalog_repository.SVNCatalogRepository(node)
elif (scmType == "git"):
return git_catalog_repository.GITCatalogRepository(node)
elif (scmType == "git-discrete"):
return git_discrete_repository.GitDiscreteSCM(node)
elif (scmType == None):
2015-06-05 05:09:46 +08:00
raise RuntimeError("No scm/type defined in catalog configuration")
else:
raise RuntimeError("Unspported SCM type:" + scmType)
2015-09-25 08:45:42 +08:00
def initRepositories():
repositories = []
for scm in config.getChildren("scm"):
scmRepo = initScmRepository(scm)
if args.update or (not args.noupdate and scm.getValue("update")):
scmRepo.update()
# presumably include repos in parse path
# TODO: make this configurable
includePaths.append(scmRepo.path)
repositories.append(scmRepo)
return repositories
2015-06-05 05:09:46 +08:00
def processUpload(node, outputPath):
if args.noupload or not node.getValue("enabled", True):
print "Upload disabled"
return
2015-06-05 05:09:46 +08:00
uploadType = node.getValue("type")
if (uploadType == "rsync"):
subprocess.call(["rsync", node.getValue("args", "-az"), ".",
2015-06-05 05:09:46 +08:00
node.getValue("remote")],
cwd = outputPath)
2015-07-23 11:35:57 +08:00
elif (uploadType == "rsync-ssh"):
print "Doing rsync upload to:", node.getValue("remote")
2015-07-23 11:35:57 +08:00
subprocess.call(["rsync", node.getValue("args", "-azve"),
"ssh", ".",
node.getValue("remote")],
cwd = outputPath)
elif (uploadType == "scp"):
2015-07-23 11:35:57 +08:00
subprocess.call(["scp", node.getValue("args", "-r"), ".",
node.getValue("remote")],
cwd = outputPath)
2015-06-05 05:09:46 +08:00
else:
raise RuntimeError("Unsupported upload type:" + uploadType)
2015-07-30 02:54:45 +08:00
def parseExistingCatalog():
global existingCatalogPath
global previousCatalog
# contains existing catalog
existingCatalogPath = os.path.join(outPath, 'catalog.xml')
if not os.path.exists(existingCatalogPath):
url = config.getValue("template/url")
print "Attempting downloading from", url
try:
# can happen on new or from clean, try to pull current
# catalog from the upload location
response = urllib2.urlopen(url, timeout = 5)
content = response.read()
f = open(existingCatalogPath, 'w' )
f.write( content )
f.close()
print "...worked"
except urllib2.URLError as e:
print "Downloading current catalog failed", e, "from", url
2015-07-23 11:35:57 +08:00
rootDir = args.dir
if not os.path.isabs(rootDir):
rootDir = os.path.abspath(rootDir)
os.chdir(rootDir)
2015-06-05 05:09:46 +08:00
configPath = 'catalog.config.xml'
if not os.path.exists(configPath):
2015-06-05 05:09:46 +08:00
raise RuntimeError("no config file found at:" + configPath)
config = sgprops.readProps(configPath)
2015-06-05 05:09:46 +08:00
# out path
outPath = config.getValue('output-dir')
if outPath is None:
# default out path
outPath = os.path.join(rootDir, "output")
elif not os.path.isabs(outPath):
outPath = os.path.join(rootDir, "output")
2015-07-23 11:35:57 +08:00
if args.clean:
print "Cleaning output"
shutil.rmtree(outPath)
if not os.path.exists(outPath):
os.mkdir(outPath)
2015-06-05 05:09:46 +08:00
thumbnailPath = os.path.join(outPath, config.getValue('thumbnail-dir', "thumbnails"))
if not os.path.exists(thumbnailPath):
os.mkdir(thumbnailPath)
2015-07-28 11:39:32 +08:00
thumbnailUrls = list(t.value for t in config.getChildren("thumbnail-url"))
for i in config.getChildren("include-dir"):
if not os.path.exists(i.value):
print "Skipping missing include path:", i.value
continue
includePaths.append(i.value)
2015-07-30 02:54:45 +08:00
parseExistingCatalog()
2015-09-25 08:45:42 +08:00
repositories = initRepositories()
2015-06-05 05:09:46 +08:00
2015-09-25 08:45:42 +08:00
for scm in repositories:
for p in scanPackages(scm):
2016-01-14 09:47:13 +08:00
try:
p.scanSetXmlFiles(includePaths)
packages[p.id] = p
except:
print "Skipping SCM package due to exception:", p.path
2015-06-05 05:09:46 +08:00
if os.path.exists(existingCatalogPath):
try:
previousCatalog = sgprops.readProps(existingCatalogPath)
except:
print "Previous catalog is malformed"
previousCatalog = sgprops.Node()
for p in previousCatalog.getChildren("package"):
pkgId = p.getValue("id")
if not pkgId in packages.keys():
print "Orphaned old package:", pkgId
continue
2015-06-05 05:09:46 +08:00
packages[pkgId].setPreviousData(p)
else:
print "No previous catalog"
2015-06-05 05:09:46 +08:00
catalogNode = sgprops.Node("catalog")
2015-06-05 05:09:46 +08:00
sgprops.copy(config.getChild("template"), catalogNode)
2015-09-28 12:15:44 +08:00
catalogNode.getChild("catalog-version", create = True).value = CATALOG_VERSION
2015-07-28 11:39:32 +08:00
mirrorUrls = list(m.value for m in config.getChildren("mirror"))
2015-06-05 05:09:46 +08:00
packagesToGenerate = []
for p in packages.values():
if p.isSourceModified or args.forcedirty:
2015-06-05 05:09:46 +08:00
packagesToGenerate.append(p)
else:
p.useExistingCatalogData()
excludeFilePath = os.path.join(rootDir, "zip-excludes.lst")
2015-07-23 11:35:57 +08:00
# def f(x):
# x.generateZip(outPath)
# x.extractThumbnails(thumbnailPath)
# return True
#
# p = Pool(8)
# print(p.map(f,packagesToGenerate))
2015-06-05 05:09:46 +08:00
for p in packagesToGenerate:
p.generateZip(outPath, excludeFilePath)
2015-07-23 11:35:57 +08:00
p.extractThumbnails(thumbnailPath)
print "Creating catalog"
for p in packages.values():
catalogNode.addChild(p.packageNode(mirrorUrls, thumbnailUrls[0]))
catalogNode.write(os.path.join(outPath, "catalog.xml"))
for up in config.getChildren("upload"):
processUpload(up, outPath)