1
0
Fork 0
fgmeta/maintain_catalog.py

220 lines
6.3 KiB
Python
Raw Normal View History

2015-06-04 21:09:46 +00:00
#!/usr/bin/python
2015-07-29 18:54:45 +00:00
import os, sys, re, glob, shutil
2015-06-04 21:09:46 +00:00
import subprocess
import sgprops
2015-07-23 03:35:57 +00:00
import argparse
import urllib2
2015-07-26 03:45:01 +00:00
import package as pkg
2015-06-04 21:09:46 +00:00
import svn_catalog_repository
import git_catalog_repository
import git_discrete_repository
2015-07-23 03:35:57 +00: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")
2015-07-28 03:39:32 +00:00
parser.add_argument("--no-update",
dest = "noupdate",
help="Disable updating from SCM source",
2015-07-28 02:45:55 +00:00
action="store_true")
2015-07-23 03:35:57 +00:00
parser.add_argument("dir", help="Catalog directory")
args = parser.parse_args()
includePaths = []
2015-09-25 00:45:42 +00:00
packages = {}
2015-07-15 02:37:39 +00:00
def scanPackages(scmRepo):
2015-06-04 21:09:46 +00: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-04 21:09:46 +00: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-04 21:09:46 +00:00
raise RuntimeError("No scm/type defined in catalog configuration")
else:
raise RuntimeError("Unspported SCM type:" + scmType)
2015-09-25 00:45:42 +00: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-04 21:09:46 +00:00
def processUpload(node, outputPath):
if not node.getValue("enabled", True):
print "Upload disabled"
return
2015-06-04 21:09:46 +00:00
uploadType = node.getValue("type")
if (uploadType == "rsync"):
subprocess.call(["rsync", node.getValue("args", "-az"), ".",
2015-06-04 21:09:46 +00:00
node.getValue("remote")],
cwd = outputPath)
2015-07-23 03:35:57 +00:00
elif (uploadType == "rsync-ssh"):
print "Doing rsync upload to:", node.getValue("remote")
2015-07-23 03:35:57 +00:00
subprocess.call(["rsync", node.getValue("args", "-azve"),
"ssh", ".",
node.getValue("remote")],
cwd = outputPath)
elif (uploadType == "scp"):
2015-07-23 03:35:57 +00:00
subprocess.call(["scp", node.getValue("args", "-r"), ".",
node.getValue("remote")],
cwd = outputPath)
2015-06-04 21:09:46 +00:00
else:
raise RuntimeError("Unsupported upload type:" + uploadType)
2015-07-29 18:54:45 +00: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 03:35:57 +00:00
rootDir = args.dir
if not os.path.isabs(rootDir):
rootDir = os.path.abspath(rootDir)
os.chdir(rootDir)
2015-06-04 21:09:46 +00:00
configPath = 'catalog.config.xml'
if not os.path.exists(configPath):
2015-06-04 21:09:46 +00:00
raise RuntimeError("no config file found at:" + configPath)
config = sgprops.readProps(configPath)
2015-06-04 21:09:46 +00: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 03:35:57 +00:00
if args.clean:
print "Cleaning output"
shutil.rmtree(outPath)
if not os.path.exists(outPath):
os.mkdir(outPath)
2015-06-04 21:09:46 +00:00
thumbnailPath = os.path.join(outPath, config.getValue('thumbnail-dir', "thumbnails"))
if not os.path.exists(thumbnailPath):
os.mkdir(thumbnailPath)
2015-07-28 03:39:32 +00: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-29 18:54:45 +00:00
parseExistingCatalog()
2015-09-25 00:45:42 +00:00
repositories = initRepositories()
2015-06-04 21:09:46 +00:00
2015-09-25 00:45:42 +00:00
for scm in repositories:
for p in scanPackages(scm):
p.scanSetXmlFiles(includePaths)
2015-06-04 21:09:46 +00:00
packages[p.id] = p
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-04 21:09:46 +00:00
packages[pkgId].setPreviousData(p)
else:
print "No previous catalog"
2015-06-04 21:09:46 +00:00
catalogNode = sgprops.Node("catalog")
2015-06-04 21:09:46 +00:00
sgprops.copy(config.getChild("template"), catalogNode)
# version 3 catalog
catalogNode.getChild("catalog-version", create = True).value = 3
2015-07-28 03:39:32 +00:00
mirrorUrls = list(m.value for m in config.getChildren("mirror"))
2015-06-04 21:09:46 +00:00
packagesToGenerate = []
for p in packages.values():
if p.isSourceModified:
2015-06-04 21:09:46 +00:00
packagesToGenerate.append(p)
else:
p.useExistingCatalogData()
excludeFilePath = os.path.join(rootDir, "zip-excludes.lst")
2015-07-23 03:35:57 +00:00
# def f(x):
# x.generateZip(outPath)
# x.extractThumbnails(thumbnailPath)
# return True
#
# p = Pool(8)
# print(p.map(f,packagesToGenerate))
2015-06-04 21:09:46 +00:00
for p in packagesToGenerate:
p.generateZip(outPath, excludeFilePath)
2015-07-23 03:35:57 +00: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)