Philipp Hörist pushed to branch master at gajim / gajim
Commits:
-
3d5363d0
by Philipp Hörist at 2022-12-04T00:41:11+01:00
9 changed files:
- .ci/appveyor_build.py
- .ci/deploy.py
- .ci/link-gtk.py
- scripts/bump_version.py
- scripts/generate_ui_types.py
- scripts/update_translations.py
- setup.py
- win/misc/create-launcher.py
- win/misc/depcheck.py
Changes:
| ... | ... | @@ -2,14 +2,14 @@ |
| 2 | 2 | |
| 3 | 3 | from typing import Any
|
| 4 | 4 | |
| 5 | +import logging
|
|
| 5 | 6 | import json
|
| 6 | 7 | import os
|
| 7 | 8 | import requests
|
| 9 | +import sys
|
|
| 8 | 10 | import time
|
| 9 | 11 | from pathlib import Path
|
| 10 | 12 | |
| 11 | -from rich.console import Console
|
|
| 12 | - |
|
| 13 | 13 | |
| 14 | 14 | ACCOUNT = 'lovetox'
|
| 15 | 15 | PROJECT_SLUG = 'gajim'
|
| ... | ... | @@ -25,7 +25,8 @@ |
| 25 | 25 | PROJECT_API_URL = f'{BASE_URL}/projects/{ACCOUNT}/{PROJECT_SLUG}'
|
| 26 | 26 | |
| 27 | 27 | |
| 28 | -console = Console()
|
|
| 28 | +logging.basicConfig(level='INFO', format='%(levelname)s: %(message)s')
|
|
| 29 | +log = logging.getLogger()
|
|
| 29 | 30 | |
| 30 | 31 | |
| 31 | 32 | def get_gajim_version() -> str:
|
| ... | ... | @@ -34,13 +35,13 @@ def get_gajim_version() -> str: |
| 34 | 35 | |
| 35 | 36 | tag = os.environ.get('CI_COMMIT_TAG')
|
| 36 | 37 | if tag is None:
|
| 37 | - exit('No tag found')
|
|
| 38 | + sys.exit('No tag found')
|
|
| 38 | 39 | return tag
|
| 39 | 40 | |
| 40 | 41 | |
| 41 | 42 | def push_yaml_to_project() -> None:
|
| 42 | - console.print('Push settings ...')
|
|
| 43 | - with open('.ci/appveyor.yml', 'r') as file:
|
|
| 43 | + log.info('Push settings ...')
|
|
| 44 | + with open('.ci/appveyor.yml') as file:
|
|
| 44 | 45 | yaml = file.read()
|
| 45 | 46 | |
| 46 | 47 | req = requests.put(SETTINGS_API_URL, data=yaml, headers=HEADERS)
|
| ... | ... | @@ -48,7 +49,7 @@ def push_yaml_to_project() -> None: |
| 48 | 49 | |
| 49 | 50 | |
| 50 | 51 | def start_build() -> str:
|
| 51 | - console.print('Start build ...')
|
|
| 52 | + log.info('Start build ...')
|
|
| 52 | 53 | payload = {
|
| 53 | 54 | 'accountName': ACCOUNT,
|
| 54 | 55 | 'projectSlug': PROJECT_SLUG,
|
| ... | ... | @@ -66,7 +67,7 @@ def start_build() -> str: |
| 66 | 67 | |
| 67 | 68 | def is_build_finished(build: dict[str, str]) -> bool:
|
| 68 | 69 | if build['status'] in ('failed', 'cancelled'):
|
| 69 | - exit('Found failed job')
|
|
| 70 | + sys.exit('Found failed job')
|
|
| 70 | 71 | |
| 71 | 72 | return build['status'] == 'success'
|
| 72 | 73 | |
| ... | ... | @@ -76,18 +77,18 @@ def check_for_response(build_id: str) -> None: |
| 76 | 77 | while True:
|
| 77 | 78 | time.sleep(RETRY_TIMEOUT)
|
| 78 | 79 | |
| 79 | - console.print('Check build status ...')
|
|
| 80 | + log.info('Check build status ...')
|
|
| 80 | 81 | req = requests.get(PROJECT_API_URL, headers=HEADERS)
|
| 81 | 82 | req.raise_for_status()
|
| 82 | 83 | response = req.json()
|
| 83 | 84 | build = response['build']
|
| 84 | 85 | if build_id != build['buildId']:
|
| 85 | - exit('Unable to find buildid: %s' % build_id)
|
|
| 86 | + sys.exit('Unable to find buildid: %s' % build_id)
|
|
| 86 | 87 | |
| 87 | 88 | if is_build_finished(build):
|
| 88 | 89 | break
|
| 89 | 90 | |
| 90 | - console.print('Build status:', build['status'])
|
|
| 91 | + log.info('Build status: %s', build['status'])
|
|
| 91 | 92 | |
| 92 | 93 | build_folder = Path.cwd() / 'build'
|
| 93 | 94 | build_folder.mkdir()
|
| ... | ... | @@ -96,7 +97,7 @@ def check_for_response(build_id: str) -> None: |
| 96 | 97 | response = get_job_response(job['jobId'])
|
| 97 | 98 | result = build_folder / f'{job["jobId"]}.json'
|
| 98 | 99 | result.write_text(json.dumps(response))
|
| 99 | - console.print('Write job response:', result)
|
|
| 100 | + log.info('Write job response: %s', result)
|
|
| 100 | 101 | |
| 101 | 102 | |
| 102 | 103 | def get_job_response(job_id: str) -> list[dict[str, Any]]:
|
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | from typing import Optional
|
| 5 | 5 | |
| 6 | 6 | import functools
|
| 7 | +import logging
|
|
| 7 | 8 | import json
|
| 8 | 9 | import os
|
| 9 | 10 | import sys
|
| ... | ... | @@ -12,7 +13,6 @@ |
| 12 | 13 | from pathlib import Path
|
| 13 | 14 | |
| 14 | 15 | import requests
|
| 15 | -from rich.console import Console
|
|
| 16 | 16 | |
| 17 | 17 | |
| 18 | 18 | FTP_URL = 'panoramix.gajim.org'
|
| ... | ... | @@ -27,17 +27,19 @@ |
| 27 | 27 | |
| 28 | 28 | RELEASE_FOLDER_BASE = 'downloads'
|
| 29 | 29 | |
| 30 | -console = Console()
|
|
| 30 | + |
|
| 31 | +logging.basicConfig(level='INFO', format='%(levelname)s: %(message)s')
|
|
| 32 | +log = logging.getLogger()
|
|
| 31 | 33 | |
| 32 | 34 | |
| 33 | 35 | def ftp_connection(func: Any) -> Any:
|
| 34 | 36 | @functools.wraps(func)
|
| 35 | 37 | def func_wrapper(filedir: Path) -> None:
|
| 36 | 38 | ftp = FTP_TLS(FTP_URL, FTP_USER, FTP_PASS)
|
| 37 | - console.print('Successfully connected to', FTP_URL)
|
|
| 39 | + log.info('Successfully connected to %s', FTP_URL)
|
|
| 38 | 40 | func(ftp, filedir)
|
| 39 | 41 | ftp.quit()
|
| 40 | - console.print('Quit')
|
|
| 42 | + log.info('Quit')
|
|
| 41 | 43 | return
|
| 42 | 44 | return func_wrapper
|
| 43 | 45 | |
| ... | ... | @@ -50,14 +52,14 @@ def get_release_folder_from_tag(tag: str) -> str: |
| 50 | 52 | def get_gajim_tag() -> str:
|
| 51 | 53 | tag = os.environ.get('CI_COMMIT_TAG')
|
| 52 | 54 | if tag is None:
|
| 53 | - exit('No tag found')
|
|
| 55 | + sys.exit('No tag found')
|
|
| 54 | 56 | return tag
|
| 55 | 57 | |
| 56 | 58 | |
| 57 | 59 | def find_linux_tarball(filedir: Path) -> Path:
|
| 58 | 60 | files = list(filedir.glob('gajim-*.tar.gz'))
|
| 59 | 61 | if len(files) != 1:
|
| 60 | - exit('Unknown files found')
|
|
| 62 | + sys.exit('Unknown files found')
|
|
| 61 | 63 | return files[0]
|
| 62 | 64 | |
| 63 | 65 | |
| ... | ... | @@ -86,7 +88,7 @@ def upload_file(ftp: FTP_TLS, |
| 86 | 88 | if name is None:
|
| 87 | 89 | name = filepath.name
|
| 88 | 90 | |
| 89 | - console.print('Upload file', filepath.name, 'as', name)
|
|
| 91 | + log.info('Upload file %s as %s', filepath.name, name)
|
|
| 90 | 92 | with open(filepath, 'rb') as f:
|
| 91 | 93 | ftp.storbinary('STOR ' + name, f)
|
| 92 | 94 | |
| ... | ... | @@ -103,7 +105,7 @@ def download_artifacts(path: Path) -> None: |
| 103 | 105 | filename = artifact['fileName']
|
| 104 | 106 | file_url = artifact['fileUrl']
|
| 105 | 107 | |
| 106 | - console.print('Download', filename, '...')
|
|
| 108 | + log.info('Download %s', filename)
|
|
| 107 | 109 | |
| 108 | 110 | req = requests.get(file_url, headers=HEADERS)
|
| 109 | 111 | req.raise_for_status()
|
| ... | ... | @@ -3,7 +3,9 @@ |
| 3 | 3 | # Creates links from gui folder to all files in the gtk folder
|
| 4 | 4 | # This is needed for pyright to work correctly with the dynamic gui imports
|
| 5 | 5 | |
| 6 | +import logging
|
|
| 6 | 7 | from pathlib import Path
|
| 8 | +import sys
|
|
| 7 | 9 | |
| 8 | 10 | IGNORED_FILES = ['__init__.py']
|
| 9 | 11 | IGNORED_DIRS = ['__pycache__']
|
| ... | ... | @@ -11,12 +13,17 @@ |
| 11 | 13 | cwd = Path.cwd()
|
| 12 | 14 | |
| 13 | 15 | if cwd.name != 'gajim':
|
| 14 | - exit('Script needs to be excecuted from gajim repository root directory')
|
|
| 16 | + sys.exit('Script needs to be excecuted from gajim repository '
|
|
| 17 | + 'root directory')
|
|
| 15 | 18 | |
| 16 | 19 | gui_path = cwd / 'gajim' / 'gui'
|
| 17 | 20 | gtk_path = cwd / 'gajim' / 'gtk'
|
| 18 | 21 | |
| 19 | 22 | |
| 23 | +logging.basicConfig(level='INFO', format='%(levelname)s: %(message)s')
|
|
| 24 | +log = logging.getLogger()
|
|
| 25 | + |
|
| 26 | + |
|
| 20 | 27 | def cleanup_dir(target_dir: Path) -> None:
|
| 21 | 28 | for path in target_dir.iterdir():
|
| 22 | 29 | if path.name in IGNORED_FILES:
|
| ... | ... | @@ -31,7 +38,7 @@ def link(target: Path) -> None: |
| 31 | 38 | source = source.replace('gajim/gtk', 'gajim/gui')
|
| 32 | 39 | source = Path(source)
|
| 33 | 40 | source.symlink_to(target)
|
| 34 | - print('create symlink from', source, 'to', target)
|
|
| 41 | + log.info('create symlink from %s -> %s', source, target)
|
|
| 35 | 42 | |
| 36 | 43 | |
| 37 | 44 | def link_files(source_dir: Path) -> None:
|
| 1 | 1 | #!/usr/bin/env python3
|
| 2 | 2 | |
| 3 | -import re
|
|
| 4 | 3 | import argparse
|
| 5 | 4 | from datetime import datetime
|
| 6 | 5 | from pathlib import Path
|
| 6 | +import re
|
|
| 7 | 7 | import subprocess
|
| 8 | +import sys
|
|
| 8 | 9 | |
| 9 | 10 | REPO_DIR = Path(__file__).resolve().parent.parent
|
| 10 | 11 | |
| ... | ... | @@ -23,7 +24,7 @@ def get_current_version() -> str: |
| 23 | 24 | |
| 24 | 25 | match = re.search(VERSION_RX, content)
|
| 25 | 26 | if match is None:
|
| 26 | - exit('Unable to find current version')
|
|
| 27 | + sys.exit('Unable to find current version')
|
|
| 27 | 28 | return match[0]
|
| 28 | 29 | |
| 29 | 30 |
| ... | ... | @@ -3,15 +3,21 @@ |
| 3 | 3 | # Reads all .ui files and creates builder.pyi
|
| 4 | 4 | # Excecute this script from the repo root dir
|
| 5 | 5 | |
| 6 | +import logging
|
|
| 7 | +import sys
|
|
| 6 | 8 | from io import TextIOWrapper
|
| 7 | 9 | from pathlib import Path
|
| 8 | -from xml.etree import ElementTree as ET
|
|
| 10 | +from xml.etree import ElementTree
|
|
| 9 | 11 | |
| 10 | 12 | |
| 13 | +logging.basicConfig(level='INFO', format='%(levelname)s: %(message)s')
|
|
| 14 | +log = logging.getLogger()
|
|
| 15 | + |
|
| 11 | 16 | cwd = Path.cwd()
|
| 12 | 17 | |
| 13 | 18 | if cwd.name != 'gajim':
|
| 14 | - exit('Script needs to be excecuted from gajim repository root directory')
|
|
| 19 | + sys.exit('Script needs to be excecuted from gajim repository '
|
|
| 20 | + 'root directory')
|
|
| 15 | 21 | |
| 16 | 22 | in_path = cwd / 'gajim' / 'data' / 'gui'
|
| 17 | 23 | out_path = cwd / 'gajim' / 'gtk' / 'builder.pyi'
|
| ... | ... | @@ -45,14 +51,14 @@ def get_builder(file_name: str, widgets: list[str] = ...) -> Builder: ...''' |
| 45 | 51 | def make_class_name(path: Path) -> str:
|
| 46 | 52 | name = path.name.removesuffix('.ui')
|
| 47 | 53 | names = name.split('_')
|
| 48 | - names = map(lambda x: x.capitalize(), names)
|
|
| 54 | + names = [name.capitalize() for name in names]
|
|
| 49 | 55 | return ''.join(names) + 'Builder'
|
| 50 | 56 | |
| 51 | 57 | |
| 52 | 58 | def parse(path: Path, file: TextIOWrapper) -> str:
|
| 53 | - print('read', path)
|
|
| 59 | + log.info('Read %s', path)
|
|
| 54 | 60 | lines: list[str] = []
|
| 55 | - tree = ET.parse(path)
|
|
| 61 | + tree = ElementTree.parse(path)
|
|
| 56 | 62 | for node in tree.iter(tag='object'):
|
| 57 | 63 | id_ = node.attrib.get('id')
|
| 58 | 64 | if id_ is None:
|
| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | |
| 24 | 24 | |
| 25 | 25 | def template_is_equal(old_template_path: Path, new_template: str) -> bool:
|
| 26 | - with open(old_template_path, 'r', encoding='utf8') as f:
|
|
| 26 | + with open(old_template_path, encoding='utf8') as f:
|
|
| 27 | 27 | old_template = f.read()
|
| 28 | 28 | |
| 29 | 29 | pattern = r'"POT-Creation-Date: .*\n"'
|
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | |
| 5 | 5 | from typing import cast
|
| 6 | 6 | |
| 7 | +import logging
|
|
| 7 | 8 | import os
|
| 8 | 9 | import sys
|
| 9 | 10 | |
| ... | ... | @@ -38,6 +39,10 @@ |
| 38 | 39 | ALL_LINGUAS = sorted([lang.stem for lang in TRANS_DIR.glob('*.po')])
|
| 39 | 40 | |
| 40 | 41 | |
| 42 | +logging.basicConfig(level='INFO', format='%(levelname)s: %(message)s')
|
|
| 43 | +log = logging.getLogger()
|
|
| 44 | + |
|
| 45 | + |
|
| 41 | 46 | def newer(source: Path, target: Path) -> bool:
|
| 42 | 47 | if not source.exists():
|
| 43 | 48 | raise ValueError('file "%s" does not exist' % source.resolve())
|
| ... | ... | @@ -67,7 +72,7 @@ def build_translation() -> None: |
| 67 | 72 | cwd=REPO_DIR,
|
| 68 | 73 | check=True)
|
| 69 | 74 | |
| 70 | - print('Compiling %s >> %s' % (po_file, mo_file))
|
|
| 75 | + log.info('Compiling %s >> %s', po_file, mo_file)
|
|
| 71 | 76 | |
| 72 | 77 | |
| 73 | 78 | def install_trans(data_files: DataFilesT) -> None:
|
| ... | ... | @@ -99,7 +104,7 @@ def build_man() -> None: |
| 99 | 104 | with open(filename, 'rb') as f_in,\
|
| 100 | 105 | gzip.open(man_file_gz, 'wb') as f_out:
|
| 101 | 106 | f_out.writelines(f_in)
|
| 102 | - print('Compiling %s >> %s' % (filename, man_file_gz))
|
|
| 107 | + log.info('Compiling %s >> %s', filename, man_file_gz)
|
|
| 103 | 108 | |
| 104 | 109 | |
| 105 | 110 | def install_man(data_files: DataFilesT) -> None:
|
| ... | ... | @@ -148,7 +153,7 @@ def merge(in_file: Path, |
| 148 | 153 | msg = ('ERROR: %s was not merged into the translation files!\n' %
|
| 149 | 154 | out_file)
|
| 150 | 155 | raise SystemExit(msg)
|
| 151 | - print('Compiling %s >> %s' % (in_file, out_file))
|
|
| 156 | + log.info('Compiling %s >> %s', in_file, out_file)
|
|
| 152 | 157 | |
| 153 | 158 | |
| 154 | 159 | class build(_build):
|
| ... | ... | @@ -50,8 +50,9 @@ def get_build_args() -> list[str]: |
| 50 | 50 | |
| 51 | 51 | def build_exe(source_path: str,
|
| 52 | 52 | resource_path: str,
|
| 53 | - is_gui: bool,
|
|
| 54 | - out_path: str) -> None:
|
|
| 53 | + out_path: str,
|
|
| 54 | + *,
|
|
| 55 | + is_gui: bool) -> None:
|
|
| 55 | 56 | |
| 56 | 57 | args = ['gcc', '-s']
|
| 57 | 58 | if is_gui:
|
| ... | ... | @@ -61,7 +62,7 @@ def build_exe(source_path: str, |
| 61 | 62 | subprocess.check_call(args)
|
| 62 | 63 | |
| 63 | 64 | |
| 64 | -def get_launcher_code(debug: bool) -> str:
|
|
| 65 | +def get_launcher_code(*, debug: bool) -> str:
|
|
| 65 | 66 | template = '''\
|
| 66 | 67 | #include "Python.h"
|
| 67 | 68 | #define WIN32_LEAN_AND_MEAN
|
| ... | ... | @@ -166,8 +167,9 @@ def build_launcher(out_path: str, |
| 166 | 167 | product_name: str,
|
| 167 | 168 | product_version: str,
|
| 168 | 169 | company_name: str,
|
| 170 | + *,
|
|
| 169 | 171 | is_gui: bool,
|
| 170 | - debug: bool = False) -> None:
|
|
| 172 | + debug: bool) -> None:
|
|
| 171 | 173 | |
| 172 | 174 | src_ico = os.path.abspath(icon_path)
|
| 173 | 175 | target = os.path.abspath(out_path)
|
| ... | ... | @@ -179,7 +181,7 @@ def build_launcher(out_path: str, |
| 179 | 181 | try:
|
| 180 | 182 | os.chdir(temp)
|
| 181 | 183 | with open('launcher.c', 'w') as h:
|
| 182 | - h.write(get_launcher_code(debug))
|
|
| 184 | + h.write(get_launcher_code(debug=debug))
|
|
| 183 | 185 | shutil.copyfile(src_ico, 'launcher.ico')
|
| 184 | 186 | with open('launcher.rc', 'w') as h:
|
| 185 | 187 | h.write(get_resouce_code(
|
| ... | ... | @@ -187,7 +189,7 @@ def build_launcher(out_path: str, |
| 187 | 189 | 'launcher.ico', product_name, product_version, company_name))
|
| 188 | 190 | |
| 189 | 191 | build_resource('launcher.rc', 'launcher.res')
|
| 190 | - build_exe('launcher.c', 'launcher.res', is_gui, target)
|
|
| 192 | + build_exe('launcher.c', 'launcher.res', target, is_gui=is_gui)
|
|
| 191 | 193 | finally:
|
| 192 | 194 | os.chdir(dir_)
|
| 193 | 195 | shutil.rmtree(temp)
|
| ... | ... | @@ -205,12 +207,12 @@ def main() -> None: |
| 205 | 207 | build_launcher(
|
| 206 | 208 | os.path.join(target, 'Gajim.exe'),
|
| 207 | 209 | os.path.join(misc, 'gajim.ico'), 'Gajim', 'Gajim',
|
| 208 | - version, company_name, True)
|
|
| 210 | + version, company_name, is_gui=True, debug=False)
|
|
| 209 | 211 | |
| 210 | 212 | build_launcher(
|
| 211 | 213 | os.path.join(target, 'Gajim-Debug.exe'),
|
| 212 | 214 | os.path.join(misc, 'gajim.ico'), 'Gajim', 'Gajim',
|
| 213 | - version, company_name, False, debug=True)
|
|
| 215 | + version, company_name, is_gui=False, debug=True)
|
|
| 214 | 216 | |
| 215 | 217 | # build_launcher(
|
| 216 | 218 | # os.path.join(target, "history_manager.exe"),
|
| ... | ... | @@ -12,12 +12,16 @@ |
| 12 | 12 | import subprocess
|
| 13 | 13 | import os
|
| 14 | 14 | import sys
|
| 15 | +import logging
|
|
| 15 | 16 | from typing import Optional
|
| 16 | 17 | |
| 17 | 18 | import gi
|
| 18 | 19 | gi.require_version('GIRepository', '2.0')
|
| 19 | 20 | from gi.repository import GIRepository # noqa: E402
|
| 20 | 21 | |
| 22 | +logging.basicConfig(level='INFO', format='%(levelname)s: %(message)s')
|
|
| 23 | +log = logging.getLogger()
|
|
| 24 | + |
|
| 21 | 25 | |
| 22 | 26 | def get_required_by_typelibs() -> set[str]:
|
| 23 | 27 | deps: set[str] = set()
|
| ... | ... | @@ -49,7 +53,7 @@ def get_dependencies(filename: str) -> list[str]: |
| 49 | 53 | try:
|
| 50 | 54 | data = subprocess.getoutput('objdump -p %s' % filename)
|
| 51 | 55 | except Exception as error:
|
| 52 | - print(error)
|
|
| 56 | + log.error(error)
|
|
| 53 | 57 | return deps
|
| 54 | 58 | |
| 55 | 59 | for line in data.splitlines():
|
| ... | ... | @@ -79,12 +83,12 @@ def get_things_to_delete(root: str) -> list[str]: |
| 79 | 83 | all_libs.add(lib)
|
| 80 | 84 | needed.add(lib)
|
| 81 | 85 | if find_lib(root, lib) is None:
|
| 82 | - print('MISSING:', path, lib)
|
|
| 86 | + log.info('MISSING: %s %s', path, lib)
|
|
| 83 | 87 | |
| 84 | 88 | for lib in get_required_by_typelibs():
|
| 85 | 89 | needed.add(lib)
|
| 86 | 90 | if find_lib(root, lib) is None:
|
| 87 | - print('MISSING:', lib)
|
|
| 91 | + log.info('MISSING: %s', lib)
|
|
| 88 | 92 | |
| 89 | 93 | result: list[str] = []
|
| 90 | 94 | libs = all_libs - needed
|
| ... | ... | @@ -106,7 +110,7 @@ def main() -> None: |
| 106 | 110 | libs = get_things_to_delete(sys.prefix)
|
| 107 | 111 | while libs:
|
| 108 | 112 | for lib in libs:
|
| 109 | - print('DELETE:', lib)
|
|
| 113 | + log.info('DELETE: %s', lib)
|
|
| 110 | 114 | os.unlink(lib)
|
| 111 | 115 | libs = get_things_to_delete(sys.prefix)
|
| 112 | 116 |