Commit | Line | Data |
---|---|---|
8ee66edd FC |
1 | '''Tools for making the builds.''' |
2 | from os import walk, chdir, getcwd | |
e65a09cf FC |
3 | from os.path import join, exists, dirname, getmtime, sep |
4 | from subprocess import PIPE, run | |
8ee66edd FC |
5 | from time import strftime |
6 | from pathlib import Path | |
7 | from hashlib import md5 | |
8 | ||
9 | ||
e65a09cf | 10 | # TODO refactor: make class BuilderTools |
8ee66edd FC |
11 | |
12 | ||
13 | def 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 | ||
21 | def _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 |
49 | def _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 |
71 | def _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 | ||
100 | def 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 | ||
109 | def __files_ext(fnames, _extensions): | |
110 | return [fname for fname in fnames | |
111 | if any(fname.endswith('.' + ext) for ext in _extensions)] | |
112 | ||
113 | ||
114 | def __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 | ||
143 | def 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 | ||
151 | class 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 |