From fea20a73d4580ab31a1578e964e0f5f1c5bf81a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 14 Nov 2023 16:54:00 +0100 Subject: [PATCH 1/5] packaging: Use meson's default wrap mode ci should be allowed to download gmobile --- debian/rules | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian/rules b/debian/rules index 51b4929..0b3673d 100755 --- a/debian/rules +++ b/debian/rules @@ -2,6 +2,8 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all +CONFIGURE_OPTS=--wrap-mode=default + ifneq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) CONFIGURE_OPTS += -Dtests=false endif From d83397279ff52ae021c2666285b0c0136b4f657c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 14 Nov 2023 10:59:49 +0100 Subject: [PATCH 2/5] build: Switch gmobile to 0.0.4 We switch to a wrap which helps us to avoid the submodule --- .gitignore | 1 + .gitlab-ci.yml | 4 ---- .gitmodules | 2 +- subprojects/gmobile | 1 - subprojects/gmobile.wrap | 5 +++++ 5 files changed, 7 insertions(+), 6 deletions(-) delete mode 160000 subprojects/gmobile create mode 100644 subprojects/gmobile.wrap diff --git a/.gitignore b/.gitignore index 505f5f7..0a1c927 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ debian/libfeedback-0.0-0/ debian/libfeedback-dev.substvars debian/libfeedback-dev/ debian/tmp/ +subprojects/gmobile/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 256e96b..42cf82b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,10 +2,6 @@ include: - remote: 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-definitions.yml' - remote: 'https://gitlab.freedesktop.org/freedesktop/ci-templates/-/raw/34039cd573a2df832d465bc9e4c5f543571f5241/templates/ci-fairy.yml' -variables: - GIT_SUBMODULE_STRATEGY: normal - GIT_SUBMODULE_DEPTH: 1 - stages: - build - test diff --git a/.gitmodules b/.gitmodules index fae72b7..fe9e9c5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "subprojects/gmobile"] path = subprojects/gmobile - url = https://gitlab.gnome.org/guidog/gmobile.git + url = https://gitlab.gnome.org/World/Phosh/gmobile.git diff --git a/subprojects/gmobile b/subprojects/gmobile deleted file mode 160000 index d483537..0000000 --- a/subprojects/gmobile +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d483537aee4778b114ce5d50c4c8a9f8d58337ed diff --git a/subprojects/gmobile.wrap b/subprojects/gmobile.wrap new file mode 100644 index 0000000..85901c3 --- /dev/null +++ b/subprojects/gmobile.wrap @@ -0,0 +1,5 @@ +[wrap-git] +directory=gmobile +url=https://gitlab.gnome.org/World/Phosh/gmobile.git +revision=v0.0.4 +depth=1 From 6c9cadc00947c48515855f88b905b575b3d00729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 14 Nov 2023 10:55:27 +0100 Subject: [PATCH 3/5] ci: Switch to trixie --- .gitlab-ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 42cf82b..a49d959 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,14 +16,14 @@ stages: .image: &image image: - name: debian:bookworm + name: debian:trixie .tags: &tags tags: - librem5:arm64 # Regular, full build -build:native-debian-bookworm:full: +build:native-debian-trixie:full: <<: *tags <<: *image <<: *before_script @@ -39,7 +39,7 @@ build:native-debian-bookworm:full: - $PKG_ONLY == "1" # Minimal build for e.g. submodule usage -build:native-debian-bookworm:lib: +build:native-debian-trixie:lib: <<: *tags <<: *image <<: *before_script @@ -51,13 +51,13 @@ build:native-debian-bookworm:lib: variables: - $PKG_ONLY == "1" -test:native-debian-bookworm: +test:native-debian-trixie: <<: *tags <<: *image <<: *before_script stage: test needs: - - build:native-debian-bookworm:full + - build:native-debian-trixie:full coverage: '/^\s+lines\.+:\s+([\d.]+\%)\s+/' script: - dbus-run-session ninja -C _build test coverage @@ -65,9 +65,9 @@ test:native-debian-bookworm: variables: - $PKG_ONLY == "1" -package:deb-debian-bookwarm:arm64: +package:deb-debian-trixie:arm64: variables: - L5_DOCKER_IMAGE: debian:bookworm + L5_DOCKER_IMAGE: debian:trixie extends: .l5-build-debian-package tags: - librem5:arm64 From ba4576d4907e1f3df5a94e441b07c42968bd43ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 14 Nov 2023 10:57:49 +0100 Subject: [PATCH 4/5] ci: Add uncrustify config and checker Based on what we added to phoc recently --- .gitlab-ci/check-style.py | 169 ++++++++++++++++++++++++++++++++++++++ .gitlab-ci/uncrustify.cfg | 109 ++++++++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100755 .gitlab-ci/check-style.py create mode 100644 .gitlab-ci/uncrustify.cfg diff --git a/.gitlab-ci/check-style.py b/.gitlab-ci/check-style.py new file mode 100755 index 0000000..454ddca --- /dev/null +++ b/.gitlab-ci/check-style.py @@ -0,0 +1,169 @@ +#!/bin/env python3 +# +# Based on check-style.py by +# Carlos Garnacho + +import argparse +import os +import re +import subprocess +import sys +import tempfile + +# Path relative to this script +uncrustify_cfg = '.gitlab-ci/uncrustify.cfg' + + +def run_diff(sha): + proc = subprocess.run( + ["git", "diff", "-U0", "--function-context", sha, "HEAD"], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + encoding="utf-8", + ) + return proc.stdout.strip().splitlines() + + +def find_chunks(diff): + file_entry_re = re.compile(r'^\+\+\+ b/(.*)$') + diff_chunk_re = re.compile(r'^@@ -\d+,\d+ \+(\d+),(\d+)') + file = None + chunks = [] + + for line in diff: + match = file_entry_re.match(line) + if match: + file = match.group(1) + + match = diff_chunk_re.match(line) + if match: + start = int(match.group(1)) + len = int(match.group(2)) + end = start + len + + if len > 0 and (file.endswith('.c') or file.endswith('.h') or file.endswith('.vala')): + chunks.append({'file': file, 'start': start, 'end': end}) + + return chunks + + +def reformat_chunks(chunks, rewrite, dry_run): + # Creates temp file with INDENT-ON/OFF comments + def create_temp_file(file, start, end): + with open(file) as f: + tmp = tempfile.NamedTemporaryFile() + if start > 1: + tmp.write(b'/** *INDENT-OFF* **/\n') + for i, line in enumerate(f, start=1): + if i == start - 1: + tmp.write(b'/** *INDENT-ON* **/\n') + + tmp.write(bytes(line, 'utf-8')) + if i == end - 1: + tmp.write(b'/** *INDENT-OFF* **/\n') + tmp.seek(0) + return tmp + + # Removes uncrustify INDENT-ON/OFF helper comments + def remove_indent_comments(output): + tmp = tempfile.NamedTemporaryFile() + for line in output: + if line != b'/** *INDENT-OFF* **/\n' and line != b'/** *INDENT-ON* **/\n': + tmp.write(line) + + tmp.seek(0) + return tmp + + changed = None + for chunk in chunks: + # Add INDENT-ON/OFF comments + tmp = create_temp_file(chunk['file'], chunk['start'], chunk['end']) + + # uncrustify chunk + proc = subprocess.run( + ["uncrustify", "-c", uncrustify_cfg, "-f", tmp.name], + stdout=subprocess.PIPE, + ) + reindented = proc.stdout.splitlines(keepends=True) + if proc.returncode != 0: + continue + + tmp.close() + + # Remove INDENT-ON/OFF comments + formatted = remove_indent_comments(reindented) + + if dry_run is True: + # Show changes + proc = subprocess.run( + ["diff", "-up", "--color=always", chunk['file'], formatted.name], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + encoding="utf-8", + ) + diff = proc.stdout + if diff != '': + output = re.sub('\t', '↦\t', diff) + print(output) + changed = True + else: + # Apply changes + diff = subprocess.run( + ["diff", "-up", chunk['file'], formatted.name], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + subprocess.run(["patch", chunk['file']], input=diff.stdout) + + formatted.close() + + return changed + + +def main(argv): + parser = argparse.ArgumentParser(description='Check code style. Needs uncrustify installed.') + parser.add_argument('--sha', metavar='SHA', type=str, + help='SHA for the commit to compare HEAD with') + parser.add_argument('--dry-run', '-d', type=bool, + action=argparse.BooleanOptionalAction, + help='Only print changes to stdout, do not change code') + parser.add_argument('--rewrite', '-r', type=bool, + action=argparse.BooleanOptionalAction, + help='Whether to amend the result to the last commit (e.g. \'git rebase --exec "%(prog)s -r"\')') + + if not os.path.exists('.git'): + print("Not in toplevel of a git repository", fille=sys.stderr) + return 1 + + args = parser.parse_args(argv) + sha = args.sha or 'HEAD^' + + diff = run_diff(sha) + chunks = find_chunks(diff) + changed = reformat_chunks(chunks, args.rewrite, args.dry_run) + + if args.dry_run is not True and args.rewrite is True: + proc = subprocess.run(["git", "add", "-p"]) + if proc.returncode == 0: + # Commit the added changes as a squash commit + subprocess.run( + ["git", "commit", "--squash", "HEAD", "-C", "HEAD"], + stdout=subprocess.DEVNULL) + # Delete the unapplied changes + subprocess.run(["git", "reset", "--hard"], stdout=subprocess.DEVNULL) + return 0 + elif args.dry_run is True and changed is True: + print(f""" +Issue the following commands in your local tree to apply the suggested changes: + + $ git rebase {sha} --exec "./.gitlab-ci/check-style.py -r" + $ git rebase --autosquash {sha} + +Don't trust uncrustify unconditionally. +""") + return 1 + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv[1:])) diff --git a/.gitlab-ci/uncrustify.cfg b/.gitlab-ci/uncrustify.cfg new file mode 100644 index 0000000..50be00b --- /dev/null +++ b/.gitlab-ci/uncrustify.cfg @@ -0,0 +1,109 @@ +# Indent by two spaces +indent_columns = 2 +# No tabs +indent_with_tabs = 0 +# Line length +code_width = 100 + +# +# Keywords and operators +# +# Add between 'do' and '{'. +sp_do_brace_open = add +# Add space between '}' and 'while'. +sp_brace_close_while = add +# Add 'while' and '('. +sp_while_paren_open = add +# Add or remove space around boolean operators '&&' and '||'. +sp_bool = add +# Ternary operator +sp_cond_ternary_short = remove +# Remove newline between 'struct and '{'. +nl_struct_brace = remove +# Remove newline between 'if' and '{'. +nl_if_brace = remove +# Remove newline between '}' and 'else'. +nl_brace_else = remove +# Remove newline between 'else' and '{'. +nl_else_brace = remove +# Remove newline between 'else' and 'if'. +nl_else_if = remove +# Add or remove newline between 'for' and '{'. +nl_for_brace = remove +# Treat iterators as for loops: +set FOR wl_list_for_each wl_list_for_each_reverse wl_list_for_each_safe + +# +# Function declarations, defintions and calls +# +# Add space between function name and '(' on function declaration. +sp_func_proto_paren = add +# Add or remove space between function name and '()' on function declaration +# without parameters. +sp_func_proto_paren_empty = add +# Add space between function name and '(' on function definition. +sp_func_def_paren = add +# Add or remove space between function name and '(' on function calls. +sp_func_call_paren = add +# Whether to force indentation of function definitions to start in column 1. +indent_func_def_force_col1 = true +# Add newline between return type and function name in a function definition. +nl_func_type_name = add +# Add newline between function signature and '{'. +nl_fdef_brace = add +# Whether to align variable definitions in prototypes and functions. +align_func_params = true +# The span for aligning function prototypes. +align_func_proto_span = 8 +# Add space between 'decltype(...)' and word. +sp_after_decltype = add +# Add or remove space after a pointer star '*', if followed by a function +# prototype or function definition. +sp_after_ptr_star_func = remove +# Add or remove newline between a function call's ')' and '{', as in +# 'list_for_each(item, &list) { }'. +nl_fcall_brace = add + +# +# Typedefs +# +# Add space between '}' and the name of a typedef on the same line. +sp_brace_typedef = add + +# +# Comments +# +# Add space after the opening of a C++ comment, i.e. '// A' vs. '//A'. +sp_cmt_cpp_start = add + +# +# Preprocessor +# +# Add or remove space between #else or #endif and a trailing comment. +sp_endif_cmt = add + +# Newlines at the start and end of the file. +nl_start_of_file = remove +nl_end_of_file = add +nl_end_of_file_min = 1 + +# +# Variable definitions +# +# How to align the '*' in variable definitions. +# +# 0: Part of the type 'void * foo;' (default) +# 1: Part of the variable 'void *foo;' +# 2: Dangling 'void *foo;' +# Dangling: the '*' will not be taken into account when aligning. +align_var_def_star_style = 2 +# Same for typedefs +align_typedef_star_style = 2 +# The gap for aligning struct/union member definitions. +align_var_struct_gap = 1 +# The span for aligning struct/union member definitions. +align_var_struct_span = 8 +# Remove space between pointer stars '*'. +sp_between_ptr_star = remove +# Add space before '(' of control statements ('if', 'for', 'switch', 'while', etc.) +sp_before_sparen = add From 8020ccc65cf4ad9c566d12a36e14ba5647c1d3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20G=C3=BCnther?= Date: Tue, 14 Nov 2023 11:15:13 +0100 Subject: [PATCH 5/5] ci: Run style checks on merge requests --- .gitlab-ci.yml | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a49d959..22aefb3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,8 +5,18 @@ include: stages: - build - test + - style-checks - package +workflow: + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + # Don't trigger a branch pipeline if there is an open MR + - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS + when: never + - if: $CI_COMMIT_TAG + - if: $CI_COMMIT_BRANCH + .before_script: &before_script before_script: - export DEBIAN_FRONTEND=noninteractive @@ -65,6 +75,34 @@ test:native-debian-trixie: variables: - $PKG_ONLY == "1" +format-check: + <<: *tags + <<: *image + before_script: + - export DEBIAN_FRONTEND=noninteractive + - apt-get -y update + - apt-get -y install uncrustify git python3 + stage: style-checks + needs: [] + script: + - | + if [ -n "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" ]; then + git remote add target $CI_MERGE_REQUEST_PROJECT_URL.git + echo "Fetching MR target branch $CI_MERGE_REQUEST_TARGET_BRANCH_NAME from $CI_MERGE_REQUEST_PROJECT_URL" + git fetch target "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" + git fetch --deepen=100 origin HEAD + merge_base=$(git merge-base "target/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" HEAD) + if [ -z "$merge_base" ]; then + echo "Could't determine merge base" + exit 1 + fi + echo "Merge base: $merge_base" + ./.gitlab-ci/check-style.py --dry-run --sha $merge_base + else + echo "Not a merge request" + fi + allow_failure: true + package:deb-debian-trixie:arm64: variables: L5_DOCKER_IMAGE: debian:trixie