ya2 · news · projects · code · about

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