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 | ||
ea71df6e | 13 | def exec_cmd(cmd, check=True): |
8ee66edd | 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() | |
ea71df6e | 17 | proc = run(cmd, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True, check=check) |
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: |
d68aeda7 FC |
36 | print(f'try: {root}' + 'assets/build_version.txt') |
37 | with open(root + 'assets/build_version.txt', encoding='utf8') as fver: | |
a7f2fc93 FC |
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: |
d68aeda7 | 45 | print(f'file not found: {root}' + 'assets/build_version.txt') |
a7f2fc93 | 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: | |
d68aeda7 FC |
61 | print(f'try: {root}' + 'assets/build_version.txt') |
62 | with open(root + 'assets/build_version.txt', encoding='utf8') as fver: | |
a7f2fc93 FC |
63 | __ver = fver.read() |
64 | print(f'ver: {__ver}') | |
65 | return __ver.split('-')[1] | |
dd32d640 | 66 | except FileNotFoundError: |
d68aeda7 | 67 | print(f'file not found: {root}' + 'assets/build_version.txt') |
a7f2fc93 | 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: |
d68aeda7 | 93 | with open(root + 'assets/build_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 | ||
9f095a28 | 100 | class FindFileNamesArgs: |
d3ef798c FC |
101 | |
102 | def __init__(self, extensions, excluding_directories=None, | |
103 | excluding_files_ending_with=None, root_path='.'): | |
104 | self.extensions = extensions | |
105 | self.excluding_directories = excluding_directories | |
106 | self.excluding_files_ending_with = excluding_files_ending_with | |
107 | self.root_path = root_path | |
108 | ||
109 | ||
110 | def find_file_names(find_info): | |
9f095a28 | 111 | #TODO avoid FindFileNamesArgs, write multiple functions with different |
b1af73f2 | 112 | # behaviors: this is a function which does more than one thing |
d3ef798c FC |
113 | _extensions = find_info.extensions |
114 | excl_dirs = find_info.excluding_directories | |
115 | excl_ends_with = find_info.excluding_files_ending_with | |
116 | root_path = find_info.root_path | |
8ee66edd FC |
117 | return [join(root, fname) |
118 | for root, _, fnames in walk(root_path) | |
119 | for fname in __files_ext(fnames, _extensions) | |
120 | if not any(e_d in root.split('/') for e_d in excl_dirs or []) and | |
121 | not any(fname.endswith(e_e) for e_e in excl_ends_with or [])] | |
122 | ||
123 | ||
124 | def __files_ext(fnames, _extensions): | |
125 | return [fname for fname in fnames | |
126 | if any(fname.endswith('.' + ext) for ext in _extensions)] | |
127 | ||
128 | ||
129 | def __to_be_built_single(src, tgt): | |
130 | if getmtime(tgt) > getmtime(src): | |
a7f2fc93 | 131 | print(f'{tgt} is newer than {src}: do not build') |
8ee66edd | 132 | return False |
a7f2fc93 FC |
133 | with open(src, 'rb') as fsrc: |
134 | src_content = fsrc.read() | |
135 | with open(tgt, 'rb') as ftgt: | |
136 | tgt_content = ftgt.read() | |
8ee66edd FC |
137 | hash_src = md5(src_content).hexdigest() |
138 | hash_tgt = md5(tgt_content).hexdigest() | |
139 | cache = {} | |
140 | lines = [] | |
141 | if exists('hash_cache.txt'): | |
a7f2fc93 FC |
142 | with open('hash_cache.txt', encoding='utf8') as fhash: |
143 | lines = fhash.readlines() | |
8ee66edd FC |
144 | for line in lines: |
145 | line_spl = line.split() | |
a7f2fc93 | 146 | _hash = line_spl[-1] |
8ee66edd | 147 | fname = ' '.join(line_spl[:-1]) |
a7f2fc93 | 148 | cache[fname] = _hash |
8ee66edd FC |
149 | if src in cache and tgt in cache: |
150 | if hash_src == cache[src] and \ | |
151 | hash_tgt == cache[tgt]: | |
a7f2fc93 | 152 | print(f'{tgt} and {src} are in the cache: do not build') |
8ee66edd | 153 | return False |
a7f2fc93 | 154 | print(f'{src} and {tgt} are not up-to-date: building...') |
8ee66edd FC |
155 | return True |
156 | ||
157 | ||
158 | def to_be_built(tgt, srcs): | |
159 | '''Should tgt be built (i.e. is it older?) from sources srcs?''' | |
160 | if not exists(tgt): | |
161 | print(tgt + ' does not exist: building...') | |
162 | return True | |
163 | return any(__to_be_built_single(src, tgt) for src in srcs) | |
164 | ||
165 | ||
166 | class InsideDir: | |
167 | '''Context manager for working inside a directory.''' | |
168 | ||
169 | def __init__(self, dir_): | |
170 | self.dir = dir_ | |
171 | self.old_dir = getcwd() | |
172 | ||
173 | def __enter__(self): | |
174 | chdir(self.dir) | |
175 | ||
176 | def __exit__(self, exc_type, exc_val, exc_tb): | |
177 | chdir(self.old_dir) | |
178 | ||
179 | ||
a7f2fc93 FC |
180 | # bld_dpath = 'build/' |
181 | # branch = _branch() | |
182 | # ver = _version() | |
183 | # win_fpath = '{dst_dir}{appname}-' + f'{branch}-windows.exe' | |
e65a09cf FC |
184 | # osx_fpath = '{dst_dir}{appname}-%s-osx.zip' % branch |
185 | # flatpak_fpath = '{dst_dir}{appname}-%s-flatpak' % branch | |
a7f2fc93 | 186 | # appimage_fpath = '{dst_dir}{appname}-' + f'{branch}-appimage' |
e65a09cf | 187 | # docs_fpath = '{dst_dir}{appname}-%s-docs.tar.gz' % branch |