285 lines
9.5 KiB
Python
285 lines
9.5 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import gzip, shutil, os, errno, json, subprocess, sys, getopt
|
|
from distutils import dir_util
|
|
from string import Template
|
|
|
|
__author__ = "Pavel Brychta"
|
|
__copyright__ = "Copyright (c) 2019-2020, Pavel Brychta"
|
|
__credits__ = ["Pavel Brychta"]
|
|
__license__ = "Private"
|
|
__version__ = "1.3.0"
|
|
__maintainer__ = "Pavel Brychta"
|
|
__email__ = "Pablo@xPablo.cz"
|
|
__status__ = "Beta"
|
|
|
|
PROJECT_FILE = "project.json" # soubor s popisem sestaveni projektu
|
|
|
|
project = {}
|
|
templatevars = {}
|
|
flist = None
|
|
flistcontent = ""
|
|
version = ""
|
|
|
|
|
|
# Vycisteni ciloveho adresare (bez jeho vymazu - jen vyprazdneni)
|
|
def cleanup(path):
|
|
for root, dirs, files in os.walk(path):
|
|
for f in files:
|
|
os.unlink(os.path.join(root, f))
|
|
for d in dirs:
|
|
shutil.rmtree(os.path.join(root, d), ignore_errors=True, onerror=None)
|
|
|
|
|
|
# Vytvoreni pripadne chybejici cesty
|
|
def maketree(filename):
|
|
if not os.path.exists(os.path.dirname(filename)):
|
|
try:
|
|
os.makedirs(os.path.dirname(filename))
|
|
except OSError as exc: # ochrana proti race condition
|
|
if exc.errno != errno.EEXIST:
|
|
raise
|
|
|
|
|
|
# Kopirovani adresaroveho stromu na cilove misto
|
|
def copytree(src, dst):
|
|
for item in os.listdir(src):
|
|
s = os.path.normpath(os.path.join(src, item))
|
|
d = os.path.normpath(os.path.join(dst, item))
|
|
maketree(d)
|
|
if os.path.isdir(s):
|
|
print(s + ' (D)-> ' + d)
|
|
copytree(s, d)
|
|
else:
|
|
print(s + ' (F)-> ' + d)
|
|
shutil.copy2(s, d)
|
|
|
|
|
|
# Kopirovani seznamu souboru
|
|
def copyfiles(files, ffrom, where):
|
|
|
|
for entry in files:
|
|
if "synthetic" not in entry:
|
|
inf = entry["src"]
|
|
outf = entry["dst"]
|
|
if outf == '':
|
|
outf = inf
|
|
if os.path.isdir(ffrom + inf):
|
|
copytree(ffrom + inf, where + outf)
|
|
else:
|
|
if "istemplate" in entry and entry["istemplate"]:
|
|
with open(ffrom + inf, 'r') as infile:
|
|
print(ffrom + inf + ' (T)-> ' + where + outf)
|
|
maketree(where + outf)
|
|
# https://stackoverflow.com/questions/4406102/light-weight-template-engine-for-python
|
|
form = Template(infile.read()).substitute(templatevars)
|
|
outfile = open(where + outf, 'w')
|
|
outfile.write(form)
|
|
outfile.close()
|
|
else:
|
|
with open(ffrom + inf, 'rb') as infile:
|
|
print(ffrom + inf + ' (F)-> ' + where + outf)
|
|
maketree(where + outf)
|
|
outfile = open(where + outf, 'wb')
|
|
outfile.write(infile.read())
|
|
outfile.close()
|
|
# else:
|
|
# if "istemplate" in entry and entry["istemplate"]:
|
|
# inf = entry["src"]
|
|
# with open(where + inf, 'r') as infile:
|
|
# print(where + inf + ' (ST)-> ' + where + inf)
|
|
# form = Template(infile.read()).substitute(templatevars)
|
|
# outfile = open(where + inf, 'w')
|
|
# outfile.write(form)
|
|
# outfile.close()
|
|
|
|
# Spojovani soubru
|
|
def joinfilesindir(dir, outfile):
|
|
for item in os.listdir(dir):
|
|
fn = os.path.join(dir, item)
|
|
if os.path.isfile(fn):
|
|
with open(fn, 'rb') as infile:
|
|
outfile.write(infile.read())
|
|
else:
|
|
if not fn.endswith("/"):
|
|
fn += "/"
|
|
joinfilesindir(fn, outfile)
|
|
|
|
|
|
def joinfiles(srclist, srcPath, outfName):
|
|
outfName = os.path.normpath(outfName)
|
|
maketree(outfName)
|
|
print(outfName + ' =')
|
|
with open(outfName, 'wb') as outfile:
|
|
for fname in srclist:
|
|
fname = os.path.normpath(fname)
|
|
print(' + ' + fname)
|
|
if os.path.isfile(srcPath + fname):
|
|
with open(srcPath + fname, 'rb') as infile:
|
|
outfile.write(infile.read())
|
|
else:
|
|
joinfilesindir(srcPath + fname, outfile)
|
|
outfile.close()
|
|
|
|
|
|
def copycompresstree(src, dst, compress, dirbase):
|
|
global flist
|
|
global flistcontent
|
|
|
|
for item in os.listdir(src):
|
|
s = os.path.normpath(os.path.join(src, item))
|
|
d = os.path.normpath(os.path.join(dst, item))
|
|
maketree(d)
|
|
if os.path.isdir(s):
|
|
d = os.path.normpath(os.path.join(dst, item))
|
|
print(s + ' (D)-> ' + d)
|
|
copycompresstree(s, d, compress, dirbase)
|
|
else:
|
|
dopack = 0
|
|
rpath = os.path.relpath(dst, dirbase)
|
|
if rpath == ".":
|
|
rpath = ""
|
|
else:
|
|
rpath = "/" + rpath
|
|
fignore = False
|
|
fforce = False
|
|
for entry in compress:
|
|
target = os.path.normpath(entry["src"])
|
|
if entry["dst"] != "":
|
|
target = os.path.normpath(entry["dst"])
|
|
if s.endswith(target):
|
|
if "compress" in entry and entry["compress"]:
|
|
dopack += 1
|
|
if "flistignore" in entry:
|
|
fignore = True
|
|
if "flistforce" in entry:
|
|
fforce = True
|
|
if dopack != 0:
|
|
d = os.path.normpath(os.path.join(dst, item + ".gz"))
|
|
print(s + ' (C)-> ' + d)
|
|
# packing & copying
|
|
with open(s, 'rb') as infile:
|
|
maketree(d)
|
|
outfile = gzip.open(d, 'wb')
|
|
outfile.writelines(infile)
|
|
outfile.close()
|
|
if (flist is not None) and (not fignore):
|
|
flc = item + ".gz"
|
|
if fforce:
|
|
flc += ",force"
|
|
flistcontent += rpath + "/" + flc + "\r\n"
|
|
else:
|
|
d = os.path.normpath(os.path.join(dst, item))
|
|
print(s + ' (F)-> ' + d)
|
|
shutil.copy2(s, d)
|
|
if (flist is not None) and (not fignore):
|
|
flc = item
|
|
if fforce:
|
|
flc += ",force"
|
|
flistcontent += rpath + "/" + flc + "\r\n"
|
|
|
|
|
|
# Ziskani verze repozitare z gitu
|
|
def getgitversion():
|
|
isgit = True
|
|
after = b"0"
|
|
mod = b""
|
|
try:
|
|
tag = subprocess.check_output(["git", "describe", "--tags", "--always"]).strip()
|
|
except:
|
|
tag = b"0.0.0"
|
|
isgit = False
|
|
|
|
if isgit:
|
|
if tag.find(b".") < 0:
|
|
tag = b"0.0.0"
|
|
if tag == b"0.0.0":
|
|
after = subprocess.check_output(["git", "rev-list", "--all", "--count"]).strip()
|
|
else:
|
|
if tag.find(b"-") > 0:
|
|
taginfo = tag.split(b'-')
|
|
tag = taginfo[0]
|
|
after = taginfo[1]
|
|
else:
|
|
after = subprocess.check_output(["git", "rev-list", tag + "..HEAD", "--count"]).strip()
|
|
mod = subprocess.check_output(["git", "diff-index", "HEAD"]).strip()
|
|
if after == b"0":
|
|
revision = tag
|
|
else:
|
|
revision = tag + b'.' + after
|
|
if mod != b"":
|
|
revision = revision + b"m"
|
|
else:
|
|
revision = b"0.0.0.x"
|
|
return revision.decode("utf-8")
|
|
|
|
def main(argv):
|
|
global flist
|
|
global flistcontent
|
|
|
|
projectfile = PROJECT_FILE # default jmeno projektoveho souboru
|
|
try:
|
|
opts, args = getopt.getopt(argv, "hi:o:", ["ifile="])
|
|
except getopt.GetoptError:
|
|
print("Chyba")
|
|
sys.exit(2)
|
|
for opt, arg in opts:
|
|
if opt in ("-p", "-project"):
|
|
projectfile = arg
|
|
version = getgitversion()
|
|
datadir = None
|
|
templatevars['version'] = version
|
|
print("Web version " + version)
|
|
with open(projectfile) as fd:
|
|
project = json.load(fd)
|
|
|
|
if "templatevariables" in project:
|
|
tv = project["templatevariables"]
|
|
for entry in tv:
|
|
templatevars[entry] = tv[entry]
|
|
|
|
if "build" in project:
|
|
build = project["build"]
|
|
|
|
approotdir = build["approotdir"]
|
|
outputdir = build["outputdir"]
|
|
if "datadir" in build:
|
|
datadir = build["datadir"]
|
|
if "flist" in build:
|
|
flist = build["flist"]
|
|
|
|
# Vycistime vystupni adresare
|
|
cleanup(outputdir)
|
|
if datadir is not None:
|
|
cleanup(datadir)
|
|
|
|
# Zacneme kombinaci soubou
|
|
if "combine" in build:
|
|
combine = build["combine"]
|
|
for entry in combine:
|
|
outname = entry["name"]
|
|
items = entry["items"]
|
|
joinfiles(items, approotdir, outputdir + outname)
|
|
|
|
# Pokracujeme kopirovanim souboru/adresaru
|
|
if "copy" in build:
|
|
copy = build["copy"]
|
|
copyfiles(copy, approotdir, outputdir)
|
|
|
|
# .. a koncime prekopirovanim souboru do vystupniho adresare s prubeznou kompresi pozadovanych souboru a vytvareni flist.txt
|
|
if datadir is not None:
|
|
deploy = []
|
|
if flist is not None:
|
|
flistcontent = ":" + version + "\r\n"
|
|
if "copy" in build:
|
|
deploy = build["copy"]
|
|
copycompresstree(outputdir, datadir, deploy, datadir)
|
|
if flist is not None:
|
|
with open(os.path.normpath(os.path.join(datadir, flist)), 'wb') as outfile:
|
|
outfile.write(flistcontent.encode('ascii', 'ignore'))
|
|
outfile.close()
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv[1:])
|