1
0
Fork 0
mirror of https://gitlab.gnome.org/GNOME/calls.git synced 2024-12-04 20:07:36 +00:00

ci: Use shared checks

This allows to drop the custom check-po

Part-of: <https://gitlab.gnome.org/GNOME/calls/-/merge_requests/753>
This commit is contained in:
Guido Günther 2024-09-01 08:32:58 +02:00 committed by Marge Bot
parent 4c6dcf9e04
commit 9f4be32753
6 changed files with 477 additions and 7 deletions

View file

@ -1,6 +1,9 @@
include: include:
- 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-definitions.yml' - 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-definitions.yml'
- 'https://gitlab.gnome.org/GNOME/citemplates/raw/master/flatpak/flatpak_ci_initiative.yml' - 'https://gitlab.gnome.org/GNOME/citemplates/raw/master/flatpak/flatpak_ci_initiative.yml'
- project: 'guidog/meta-phosh'
ref: '2aeb9bfe2b230ca3aeda8275e42c95f94f6723ca'
file: '/ci/phosh-common-jobs.yml'
stages: stages:
- build - build
@ -79,16 +82,10 @@ build-gtkdoc:
- _reference - _reference
check-po: check-po:
extends: build:native
stage: test stage: test
extends: .phosh-check-po
dependencies: dependencies:
- build:native - build:native
script:
# barf on untranslated C or UI files. Seems intltool
# can't be told to exit with non-zero exit status
# in this case
- cd po/
- intltool-update -m 2>&1 | grep -qs '/.*\.\(c|ui\)' && { intltool-update -m; exit 1; } || exit 0
package:deb-debian-trixie:arm64: package:deb-debian-trixie:arm64:
variables: variables:

98
.gitlab-ci/check-consistency Executable file
View file

@ -0,0 +1,98 @@
#!/bin/bash
#
# Copyright (C) 2024 The Phosh developers
# SPDX-License-Identifier: GPL-3.0-or-later
# Author: Guido Günther <agx@sigxcpu.org>
#
# Check if NEWS, changelog, meson and metainfo are in sync
set -e
COLOR=
if [ -n "${TERM}" ] && [ "${TERM}" != "dumb" ]; then
COLOR=1
fi
function log
{
local level="${1}"
local fd=2
local use_color
shift
if [ -n "${COLOR}" ]; then
[ "${level}" == warn ] || [ "${level}" == error ] || fd=1
! [ -t "${fd}" ] || use_color=1
if [ -n "${use_color}" ]; then
case "${level}" in
warn)
tput setaf 1
;;
error)
tput bold; tput setaf 1
;;
info)
tput setaf 2
;;
esac
fi
fi
echo "$@"
[ -z "${use_color}" ] || tput sgr0
}
if [ -f debian/changelog ]; then
log info "Fetching version from d/changelog"
VERSION=$(dpkg-parsechangelog -SVersion)
elif [ -f meson.build ]; then
log info "Fetching version from meson build file"
VERSION=$(sed -n "s/.*version\s*:\s*'\([0-9].*\)'.*/\1/p" meson.build)
else
log error "E: Don't know how to get version information"
exit 1
fi
echo "I: Checking for '${VERSION}'"
# News
if ! head -1 NEWS | grep -E -qs "\s+${VERSION}\s*$"; then
log error "E: Version ${VERSION} not in NEWS file"
exit 1
else
log info "I: Found matching news entry"
fi
# meson.build
MESON_VERSION="${VERSION/\~/.}"
if [ -f meson.build ]; then
if ! grep -qs "version\s*:\s*'$MESON_VERSION'" meson.build; then
log error "E: Version ${MESON_VERSION} not in meson.build file"
exit 1
else
log info "I: Found matching meson version entry"
fi
else
log info "I: no meson project"
fi
# appstream info
METAINFO=$(ls data/*metainfo.xml.in* 2>/dev/null || true)
if [ -z "${METAINFO}" ]; then
log warn "W: No metainfo"
exit 0
fi
if ! grep -qs "$MESON_VERSION\"" "${METAINFO}"; then
log error "E: Version ${MESON_VERSION} not in metainfo ${METAINFO}"
if [[ "${VERSION}" =~ ~(alpha|beta|rc) ]]; then
log info "I: Not a stable release, no metainfo is fine"
else
exit 1
fi
else
log info "I: Found matching metainfo entry"
fi

25
.gitlab-ci/check-po Executable file
View file

@ -0,0 +1,25 @@
#!/bin/bash
#
# Copyright (C) 2024 The Phosh developers
# SPDX-License-Identifier: GPL-3.0-or-later
# Author: Guido Günther <agx@sigxcpu.org>
cd po/ || exit 1
# barf on untranslated C files. Seems intltool
# can't be told to exit with non-zero exit status
# in this case
if intltool-update -m 2>&1 | grep -E -qs '/.*\.(c|ui|in)'; then
intltool-update -m
exit 1
fi
# Check for broken po files
for file in *.po; do
echo -n "Checking ${file}: "
msgfmt -v -c "${file}"
# Check for errors, msgfmt returns 0 on errors too
if msgfmt -c "${file}" 2>&1 | grep -qs 'fatal error'; then
exit 1
fi
done

185
.gitlab-ci/check-style.py Executable file
View file

@ -0,0 +1,185 @@
#!/bin/env python3
#
# Based on check-style.py by
# Carlos Garnacho <carlosg@gnome.org>
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:]))

View file

@ -0,0 +1,20 @@
patterns:
deny:
- regex: '^$CI_MERGE_REQUEST_PROJECT_URL/(-/)?merge_requests/$CI_MERGE_REQUEST_IID$'
message: Commit message must not contain a link to its own merge request
- regex: '^[^:]+: [a-z]'
message: "Commit description in commit message subject should be properly Capitalized. E.g. 'monitor: Avoid crash on unplug'"
where: subject
- regex: '^\S*\.(c|h|ui):'
message: Commit message subject prefix should not include .c, .h etc.
where: subject
- regex: '([^.]\.|[:,;])\s*$'
message: Commit message subject should not end with punctuation
where: subject
- regex: '^[A-Z]\S*:'
message: "Identifier in commit message subject should start lowercase 'monitor: Avoid crash on unplug'"
where: subject
require:
- regex: '^[a-z0-9,\.\+\-/#=_]+:'
message: "Commit message should start with a lowercase identifier 'monitor: Avoid crash on unplug'"
where: subject

145
.gitlab-ci/uncrustify.cfg Normal file
View file

@ -0,0 +1,145 @@
#
# Uncrustify config for phosh and related projects
#
# A span is the number of lines considered
# A threshold is the maximum number of columns an item is moved
# Indent by two spaces
indent_columns = 2
# No tabs
indent_with_tabs = 0
# Line length
code_width = 100
# Whether to remove superfluous semicolons
mod_remove_extra_semicolon = true
# indent goto by 1 (or -1 brace level)
indent_label = -1
# don't indent case after switch
indent_switch_case = 0
#
# 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
# Add or remove newline between 'while' and '{'.
nl_while_brace = remove
# Treat iterators as for loops:
set FOR wl_list_for_each wl_list_for_each_reverse wl_list_for_each_safe
# Remove braces on single line if/for/while statements
mod_full_brace_if = remove
mod_full_brace_for = remove
mod_full_brace_while = remove
# If any must be braced, they are all braced. If all can be unbraced, then the braces are removed.
mod_full_brace_if_chain = 1
# Remove braces around case (when there are no variables declarations)
mod_case_brace = remove
# Don't remove branches if the statement has more than one line
mod_full_brace_nl = 2
#
# Function declarations, definitions 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
# Specialcase i18n macros
set func_call_user _ N_ C_
sp_func_call_user_paren = remove
# 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 = 4
# The threshold for aligning struct/union member definitions.
align_var_struct_thresh = 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
# Add spaces around assignments and arithmethic operators
sp_assign = add
sp_arith = add