2015-06-04 21:09:46 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
|
|
|
import os, sys, re, glob
|
|
|
|
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()
|
2015-07-28 02:40:00 +00:00
|
|
|
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-23 03:35:57 +00:00
|
|
|
parser.add_argument("dir", help="Catalog directory")
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
2015-07-18 20:30:20 +00:00
|
|
|
includePaths = []
|
2015-07-15 02:37:39 +00:00
|
|
|
|
2015-06-04 21:09:46 +00:00
|
|
|
def scanPackages(globPath):
|
|
|
|
result = []
|
2015-07-11 20:47:13 +00:00
|
|
|
print "Scanning", globPath
|
|
|
|
print os.getcwd()
|
|
|
|
for d in glob.glob(globPath):
|
2015-07-18 20:30:20 +00:00
|
|
|
# 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
|
|
|
|
|
2015-07-26 03:45:01 +00:00
|
|
|
result.append(pkg.PackageData(d))
|
2015-07-11 20:47:13 +00:00
|
|
|
|
2015-06-04 21:09:46 +00:00
|
|
|
return result
|
|
|
|
|
|
|
|
def initScmRepository(node):
|
|
|
|
scmType = node.getValue("type")
|
|
|
|
if (scmType == "svn"):
|
|
|
|
svnPath = node.getValue("path")
|
2015-07-11 20:47:13 +00:00
|
|
|
return svn_catalog_repository.SVNCatalogRepository(svnPath)
|
|
|
|
elif (scmType == "git"):
|
2015-06-04 21:09:46 +00:00
|
|
|
gitPath = node.getValue("path")
|
|
|
|
usesSubmodules = node.getValue("uses-submodules", False)
|
2015-07-11 20:47:13 +00:00
|
|
|
return git_catalog_repository.GitCatalogRepository(gitPath, usesSubmodules)
|
|
|
|
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-07-11 20:47:13 +00:00
|
|
|
|
2015-06-04 21:09:46 +00:00
|
|
|
def processUpload(node, outputPath):
|
2015-07-11 20:47:13 +00:00
|
|
|
if not node.getValue("enabled", True):
|
|
|
|
print "Upload disabled"
|
|
|
|
return
|
|
|
|
|
2015-06-04 21:09:46 +00:00
|
|
|
uploadType = node.getValue("type")
|
2015-07-11 20:47:13 +00:00
|
|
|
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"):
|
|
|
|
subprocess.call(["rsync", node.getValue("args", "-azve"),
|
|
|
|
"ssh", ".",
|
|
|
|
node.getValue("remote")],
|
|
|
|
cwd = outputPath)
|
2015-07-11 20:47:13 +00:00
|
|
|
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-11 20:47:13 +00:00
|
|
|
# dictionary
|
2015-06-04 21:09:46 +00:00
|
|
|
packages = {}
|
|
|
|
|
2015-07-23 03:35:57 +00:00
|
|
|
rootDir = args.dir
|
2015-07-11 20:47:13 +00:00
|
|
|
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'
|
2015-07-11 20:47:13 +00:00
|
|
|
if not os.path.exists(configPath):
|
2015-06-04 21:09:46 +00:00
|
|
|
raise RuntimeError("no config file found at:" + configPath)
|
2015-07-11 20:47:13 +00:00
|
|
|
|
|
|
|
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
|
2015-07-11 20:47:13 +00:00
|
|
|
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)
|
|
|
|
|
2015-07-11 20:47:13 +00:00
|
|
|
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"))
|
2015-07-18 20:30:20 +00:00
|
|
|
if not os.path.exists(thumbnailPath):
|
|
|
|
os.mkdir(thumbnailPath)
|
|
|
|
|
2015-07-11 20:47:13 +00:00
|
|
|
thumbnailUrl = config.getValue('thumbnail-url')
|
|
|
|
|
2015-07-18 20:30:20 +00:00
|
|
|
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-11 20:47:13 +00:00
|
|
|
mirrorUrls = []
|
2015-06-04 21:09:46 +00:00
|
|
|
|
|
|
|
# contains existing catalog
|
|
|
|
existingCatalogPath = os.path.join(outPath, 'catalog.xml')
|
|
|
|
|
|
|
|
scmRepo = initScmRepository(config.getChild('scm'))
|
2015-07-28 02:40:00 +00:00
|
|
|
if args.update:
|
|
|
|
scmRepo.update()
|
2015-06-04 21:09:46 +00:00
|
|
|
|
|
|
|
# scan the directories in the aircraft paths
|
2015-07-11 20:47:13 +00:00
|
|
|
for g in config.getChildren("aircraft-dir"):
|
|
|
|
for p in scanPackages(g.value):
|
2015-06-04 21:09:46 +00:00
|
|
|
packages[p.id] = p
|
|
|
|
|
2015-07-23 03:35:57 +00:00
|
|
|
if not os.path.exists(existingCatalogPath):
|
|
|
|
try:
|
|
|
|
# can happen on new or from clean, try to pull current
|
|
|
|
# catalog from the upload location
|
|
|
|
response = urllib2.urlopen(config.getValue("template/url"), timeout = 5)
|
|
|
|
content = response.read()
|
|
|
|
f = open(existingCatalogPath, 'w' )
|
|
|
|
f.write( content )
|
|
|
|
f.close()
|
|
|
|
except urllib2.URLError as e:
|
|
|
|
print "Downloading current catalog failed", e
|
|
|
|
|
|
|
|
|
2015-07-11 20:47:13 +00: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-04 21:09:46 +00:00
|
|
|
|
2015-07-11 20:47:13 +00:00
|
|
|
packages[pkgId].setPreviousData(p)
|
|
|
|
else:
|
|
|
|
print "No previous catalog"
|
2015-06-04 21:09:46 +00:00
|
|
|
|
2015-07-11 20:47:13 +00:00
|
|
|
catalogNode = sgprops.Node("catalog")
|
2015-06-04 21:09:46 +00:00
|
|
|
sgprops.copy(config.getChild("template"), catalogNode)
|
|
|
|
|
2015-07-11 21:23:05 +00:00
|
|
|
mirrorUrls = (m.value for m in config.getChildren("mirror"))
|
2015-07-11 20:47:13 +00:00
|
|
|
|
2015-06-04 21:09:46 +00:00
|
|
|
packagesToGenerate = []
|
2015-07-11 20:47:13 +00:00
|
|
|
for p in packages.values():
|
2015-07-18 20:30:20 +00:00
|
|
|
p.scanSetXmlFiles(includePaths)
|
2015-07-15 02:37:39 +00:00
|
|
|
|
2015-06-04 21:09:46 +00:00
|
|
|
if (p.isSourceModified(scmRepo)):
|
|
|
|
packagesToGenerate.append(p)
|
2015-07-11 20:47:13 +00:00
|
|
|
else:
|
|
|
|
p.useExistingCatalogData()
|
|
|
|
|
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:
|
2015-07-23 03:35:57 +00:00
|
|
|
p.generateZip(outPath)
|
|
|
|
p.extractThumbnails(thumbnailPath)
|
2015-07-11 20:47:13 +00:00
|
|
|
|
|
|
|
print "Creating catalog"
|
|
|
|
for p in packages.values():
|
2015-07-26 03:45:01 +00:00
|
|
|
catalogNode.addChild(p.packageNode(scmRepo, mirrorUrls, thumbnailUrl))
|
2015-07-11 20:47:13 +00:00
|
|
|
|
|
|
|
catalogNode.write(os.path.join(outPath, "catalog.xml"))
|
|
|
|
|
|
|
|
print "Uploading"
|
2015-07-28 02:40:00 +00:00
|
|
|
for up in config.getChildren("upload"):
|
|
|
|
processUpload(up, outPath)
|