ya2 · news · projects · code · about

refactoring of functional tests
[pmachines.git] / lib / build / build.py
CommitLineData
8ee66edd
FC
1'''Tools for making the builds.'''
2from os import walk, chdir, getcwd
3from os.path import join, getsize, exists, dirname, getmtime, sep
4from subprocess import Popen, PIPE, run
dd32d640 5from logging import debug
8ee66edd
FC
6from time import strftime
7from pathlib import Path
8from hashlib import md5
9
10
11#TODO refactor: make class BuilderTools
12
13
14def exec_cmd(cmd):
15 '''Synchronously executes a command and returns its output.'''
16 #ret = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True).communicate()
17 #return ret[0].decode('utf-8').strip()
18 proc = run(cmd, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)
19 return proc.stdout.strip() + proc.stderr.strip()
20
21
22def _branch():
23 '''Returns the current branch.'''
24 git_branch = exec_cmd('git symbolic-ref HEAD').split('/')[-1].strip()
dd32d640 25 print('git_branch result: %s' % git_branch)
8ee66edd
FC
26 branches = ['master', 'rc', 'stable']
27 if git_branch in branches:
dd32d640 28 print('git_branch: %s' % git_branch)
8ee66edd
FC
29 return git_branch
30 root = str(Path(dirname(dirname(__file__))).parent) + '/'
31 if 'itch' in __file__.split(sep):
32 root = str(Path(dirname(__file__))) + '/'
8ce16d6c 33 if __file__ == '/app/bin/pmachines': # flatpak
8ee66edd
FC
34 root = '/app/bin/'
35 for branch in branches:
36 try:
dd32d640 37 print('try: %s' % root + 'assets/bld_version.txt')
8ee66edd
FC
38 with open(root + 'assets/bld_version.txt') as fver:
39 ver = fver.read()
dd32d640
FC
40 print('ver: %s' % ver)
41 #if branch in ver:
42 b2c = {'master': 'a', 'rc': 'r', 'stable': '.'}
43 if ver[1] == b2c[branch]:
8ee66edd
FC
44 return branch
45 except FileNotFoundError:
46 print('file not found: %s' % root + 'assets/bld_version.txt')
47
48
dd32d640
FC
49def _commit():
50 '''Returns the current branch.'''
51 git_commit = exec_cmd('git rev-parse HEAD')[:7]
52 print('git_commit result: %s' % git_commit)
53 if not git_commit.startswith("Can't r"):
54 return git_commit
55 root = str(Path(dirname(dirname(__file__))).parent) + '/'
56 if 'itch' in __file__.split(sep):
57 root = str(Path(dirname(__file__))) + '/'
58 if __file__ == '/app/bin/pmachines': # flatpak
59 root = '/app/bin/'
60 try:
61 print('try: %s' % root + 'assets/bld_version.txt')
62 with open(root + 'assets/bld_version.txt') as fver:
63 ver = fver.read()
64 print('ver: %s' % ver)
65 return ver.split('-')[1]
66 except FileNotFoundError:
67 print('file not found: %s' % root + 'assets/bld_version.txt')
68
69
8ee66edd
FC
70def _version():
71 '''Computes the version of the current build.'''
72 day = strftime('%y%m%d')
73 root = str(Path(dirname(dirname(__file__))).parent) + '/'
8ce16d6c 74 if __file__ == '/app/bin/pmachines': # flatpak
8ee66edd
FC
75 root = '/app/bin/'
76 if _branch() == 'stable':
77 pref, _ver = '', ''
78 if exists(root + 'assets/version.txt'):
79 with open(root + 'assets/version.txt') as fver:
80 pref = fver.read().strip() + '-' # + _branch() + '-'
81 _ver = fver.read().strip()
82 ret_ver = _ver or ('0.' + day)
83 else:
dd32d640
FC
84 #try: we want an error!
85 pref = {'master': 'a', 'rc': 'rc', '': 'runtime'}[_branch()]
86 #except KeyError:
87 # pref = 'notfound'
8ee66edd
FC
88 ret_ver = '0%s%s' % (pref, day)
89 pref = ret_ver
dd32d640 90 bld_ver = pref + '-' + _commit()
8ee66edd
FC
91 try:
92 with open(root + 'assets/bld_version.txt', 'w') as fver:
93 fver.write(bld_ver)
94 except OSError:
95 print("we can't write inside flatpaks, but we don't need it")
96 return ret_ver
97
98
99def files(_extensions, excl_dirs=None, excl_ends_with=None, root_path='.'):
100 '''Retrieves filenames in root_path with _extensions, with filters.'''
101 return [join(root, fname)
102 for root, _, fnames in walk(root_path)
103 for fname in __files_ext(fnames, _extensions)
104 if not any(e_d in root.split('/') for e_d in excl_dirs or []) and
105 not any(fname.endswith(e_e) for e_e in excl_ends_with or [])]
106
107
108def __files_ext(fnames, _extensions):
109 return [fname for fname in fnames
110 if any(fname.endswith('.' + ext) for ext in _extensions)]
111
112
113def __to_be_built_single(src, tgt):
114 if getmtime(tgt) > getmtime(src):
115 print('%s is newer than %s: do not build' % (tgt, src))
116 return False
117 with open(src, 'rb') as f:
118 src_content = f.read()
119 with open(tgt, 'rb') as f:
120 tgt_content = f.read()
121 hash_src = md5(src_content).hexdigest()
122 hash_tgt = md5(tgt_content).hexdigest()
123 cache = {}
124 lines = []
125 if exists('hash_cache.txt'):
126 with open('hash_cache.txt') as f:
127 lines = f.readlines()
128 for line in lines:
129 line_spl = line.split()
130 hash = line_spl[-1]
131 fname = ' '.join(line_spl[:-1])
132 cache[fname] = hash
133 if src in cache and tgt in cache:
134 if hash_src == cache[src] and \
135 hash_tgt == cache[tgt]:
136 print('%s and %s are in the cache: do not build' % (tgt, src))
137 return False
138 print('%s and %s are not up-to-date: building...' % (src, tgt))
139 return True
140
141
142def to_be_built(tgt, srcs):
143 '''Should tgt be built (i.e. is it older?) from sources srcs?'''
144 if not exists(tgt):
145 print(tgt + ' does not exist: building...')
146 return True
147 return any(__to_be_built_single(src, tgt) for src in srcs)
148
149
150class InsideDir:
151 '''Context manager for working inside a directory.'''
152
153 def __init__(self, dir_):
154 self.dir = dir_
155 self.old_dir = getcwd()
156
157 def __enter__(self):
158 chdir(self.dir)
159
160 def __exit__(self, exc_type, exc_val, exc_tb):
161 chdir(self.old_dir)
162
163
164bld_dpath = 'build/'
165branch = _branch()
166ver = _version()
167win_fpath = '{dst_dir}{appname}-%s-windows.exe' % branch
168#osx_fpath = '{dst_dir}{appname}-%s-osx.zip' % branch
169#flatpak_fpath = '{dst_dir}{appname}-%s-flatpak' % branch
170appimage_fpath = '{dst_dir}{appname}-%s-appimage' % branch
171docs_fpath = '{dst_dir}{appname}-%s-docs.tar.gz' % branch