Skip to content

ScreenShot & Record: Fixed crashes and added window selection support on Niri #1070

ScreenShot & Record: Fixed crashes and added window selection support on Niri

ScreenShot & Record: Fixed crashes and added window selection support on Niri #1070

Workflow file for this run

name: Automatic Code Quality Review
on:
pull_request_target:
types:
- opened
- synchronize
- reopened
paths:
- "**.qml"
permissions:
contents: read
pull-requests: write
jobs:
code-quality:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Automatic Code Quality
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
BASE_REF: ${{ github.base_ref }}
HEAD_REF: ${{ github.head_ref }}
run: |
git fetch origin "$BASE_REF"
diff_changes=$(git diff -U10000 origin/$BASE_REF...HEAD |
awk '/^diff --git.*\.qml /{found=1} /^diff --git/{if(!/\.qml /) found=0} found{print}' |
grep -vE "^(index|\+\+\+|-)") || echo "No qml file changed"
if [ -z "$diff_changes" ]; then
echo "No diff changes found!"
echo "The base ref checking: $BASE_REF"
echo "The head ref checking: $HEAD_REF"
exit 0
fi
comment_body=$(printf -- '### Automatic Code Quality Review')
issues=0
line_index=0
l_priority="[(L)]($PR_NUMBER 'Low priority, it is okay for this to remain unfixed before merging')"
h_priority="[(H)]($PR_NUMBER 'High priority, this needs to be fixed for the PR to be merged')"
function print_line() {
check_file_title
local priority=$1
local index=$2
local comment=$3
local code_line=$4
comment_body+=$(printf -- '\n- %s Line %d: %s\n```qml\n%s\n```' "$priority" "$index" "$comment" "$code_line")
}
function print_missing_property() {
check_file_title
local priority=$1
local property=$2
local code_line=$3
comment_body+=$(printf -- '\n- %s Missing required property `%s`. For example:\n```qml\n%s\n```' "$priority" "$property" "$code_line")
}
title_added=false
file_title=""
function check_file_title() {
if [ "$title_added" = false ]; then
title_added=true
comment_body+="$(printf -- '\n---\n### File: %s' "$file_title")"
fi
}
# Required Properties in Components
inBarWidget=false
inDesktopWidget=false
inDesktopWidgetSettings=false
inControlCenterWidget=false
inLauncherProvider=false
inMain=false
inPanel=false
inSettings=false
hasPluginApi=false
hasScreen=false
hasWidgetId=false
hasSection=false
hasSectionWidgetIndex=false
hasSectionWidgetsCount=false
hasWidgetSettings=false
hasLauncher=false
hasName=false
hasGeometryPlaceholder=false
hasAllowAttach=false
function reset_required_properties() {
inBarWidget=false
inDesktopWidget=false
inDesktopWidgetSettings=false
inControlCenterWidget=false
inLauncherProvider=false
inMain=false
inPanel=false
inSettings=false
hasPluginApi=false
hasScreen=false
hasWidgetId=false
hasSection=false
hasSectionWidgetIndex=false
hasSectionWidgetsCount=false
hasWidgetSettings=false
hasLauncher=false
hasName=false
hasGeometryPlaceholder=false
hasAllowAttach=false
}
function print_required_properties() {
if [ "$inBarWidget" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
if [ "$hasScreen" = false ]; then
print_missing_property "$h_priority" 'screen' 'property ShellScreen screen'
issues=$((issues + 1))
fi
if [ "$hasWidgetId" = false ]; then
print_missing_property "$h_priority" 'widgetId' 'property string widgetId: ""'
issues=$((issues + 1))
fi
if [ "$hasSection" = false ]; then
print_missing_property "$h_priority" 'section' 'property string section: ""'
issues=$((issues + 1))
fi
if [ "$hasSectionWidgetIndex" = false ]; then
print_missing_property "$h_priority" 'sectionWidgetIndex' 'property int sectionWidgetIndex: -1'
issues=$((issues + 1))
fi
if [ "$hasSectionWidgetsCount" = false ]; then
print_missing_property "$h_priority" 'sectionWidgetsCount' 'property int sectionWidgetsCount: 0'
issues=$((issues + 1))
fi
fi
if [ "$inDesktopWidget" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
fi
if [ "$inDesktopWidgetSettings" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
if [ "$hasWidgetSettings" = false ]; then
print_missing_property "$h_priority" 'widgetSettings' 'property var widgetSettings: null'
issues=$((issues + 1))
fi
fi
if [ "$inControlCenterWidget" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
if [ "$hasScreen" = false ]; then
print_missing_property "$h_priority" 'screen' 'property ShellScreen screen'
issues=$((issues + 1))
fi
fi
if [ "$inLauncherProvider" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
if [ "$hasLauncher" = false ]; then
print_missing_property "$h_priority" 'launcher' 'property var launcher: ""'
issues=$((issues + 1))
fi
if [ "$hasName" = false ]; then
print_missing_property "$h_priority" 'name' 'property string name: "Example"'
issues=$((issues + 1))
fi
fi
if [ "$inMain" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
fi
if [ "$inPanel" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
if [ "$hasGeometryPlaceholder" = false ]; then
print_missing_property "$h_priority" 'geometryPlaceholder' 'readonly property var geometryPlaceholder: panelContainer'
issues=$((issues + 1))
fi
if [ "$hasAllowAttach" = false ]; then
print_missing_property "$h_priority" 'allowAttach' 'readonly property bool allowAttach: true'
issues=$((issues + 1))
fi
fi
if [ "$inSettings" = true ]; then
if [ "$hasPluginApi" = false ]; then
print_missing_property "$h_priority" 'pluginApi' 'property var pluginApi: null'
issues=$((issues + 1))
fi
fi
}
while IFS= read -r line; do
if echo "$line" | grep -E "^diff --git" >/dev/null; then
print_required_properties
reset_required_properties
title_added=false
file_title=$(echo "$line" | sed 's/diff --git a\/\(.*\.qml\) .*/\1/g')
echo "Checking file: $file_title"
if [[ "$file_title" == */BarWidget.qml ]]; then
inBarWidget=true
elif [[ "$file_title" == */DesktopWidget.qml ]]; then
inDesktopWidget=true
elif [[ "$file_title" == */DesktopWidgetSettings.qml ]]; then
inDesktopWidgetSettings=true
elif [[ "$file_title" == */ControlCenterWidget.qml ]]; then
inControlCenterWidget=true
elif [[ "$file_title" == */LauncherProvider.qml ]]; then
inLauncherProvider=true
elif [[ "$file_title" == */Main.qml ]]; then
inMain=true
elif [[ "$file_title" == */Panel.qml ]]; then
inPanel=true
elif [[ "$file_title" == */Settings.qml ]]; then
inSettings=true
fi
elif echo "$line" | grep -E "^@@" >/dev/null; then
line_index=$(echo "$line" | grep -oE "\+[0-9]+" | grep -oE "[0-9]+")
echo "Current line index reset: $line_index"
else
if echo "$line" | grep -E "^\+" >/dev/null; then
# Only new lines should be auto checked for this type of code quality
if echo "$line" | grep -E "(border(\.width)?|spacing|pointSize|radius|margin(s)?): [1-9]+[0-9]*" >/dev/null; then
print_line "$h_priority" "$line_index" 'Do not use hardcoded values, always prefer to use the `Style` singleton instead' "$line"
issues=$((issues + 1))
fi
if echo "$line" | grep -E "console\.log" >/dev/null; then
print_line "$h_priority" "$line_index" 'Do not use `console.log`, always prefer to use the `Logger` singleton instead' "$line"
issues=$((issues + 1))
fi
if echo "$line" | grep -E "^(Text|Button|Checkbox|Switch) *\{" >/dev/null; then
print_line "$h_priority" "$line_index" 'Always prefer to use noctalia-widgets instead of qml widgets to keep it consistent with the shell. For example instead of `Text`, use `NText`' "$line"
issues=$((issues + 1))
fi
if echo "$line" | grep -E "applyUiScale: *false" >/dev/null; then
if [[ "$file_title" != *BarWidget.qml ]]; then
print_line "$l_priority" "$line_index" 'The `applyUiScale: false` would make it so that the component does not support ui scaling. Always check if this is the correct behaviour you want when changing the ui scale!' "$line"
issues=$((issues + 1))
fi
fi
if echo "$line" | grep -E "pluginApi\??\.tr\((.)*\) *(\?\?|\|\|)" >/dev/null; then
print_line "$l_priority" "$line_index" 'When it comes to translations there is no need for fallback values. From: `pluginApi?.tr("example") || "value"`. To: `pluginApi?.tr("example")`' "$line"
issues=$((issues + 1))
fi
if echo "$line" | grep -E "(text|label|description): *(\"|').+(\"|')" >/dev/null; then
print_line "$h_priority" "$line_index" 'Use translations instead of hardcoded text. Instead of: `"Example Label"`. To: `pluginApi?.tr("panel.example-label")`' "$line"
issues=$((issues + 1))
fi
fi
# Check for required properties
if [ "$inBarWidget" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
if echo "$line" | grep -E 'property +ShellScreen +screen' >/dev/null; then
hasScreen=true
fi
if echo "$line" | grep -E 'property +string +widgetId: +""' >/dev/null; then
hasWidgetId=true
fi
if echo "$line" | grep -E 'property +string +section: +""' >/dev/null; then
hasSection=true
fi
if echo "$line" | grep -E 'property +int +sectionWidgetIndex: +-1' >/dev/null; then
hasSectionWidgetIndex=true
fi
if echo "$line" | grep -E 'property +int +sectionWidgetsCount: +0' >/dev/null; then
hasSectionWidgetsCount=true
fi
fi
if [ "$inDesktopWidget" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
fi
if [ "$inDesktopWidgetSettings" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
if echo "$line" | grep -E 'property +var +widgetSettings: +null' >/dev/null; then
hasWidgetSettings=true
fi
fi
if [ "$inControlCenterWidget" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
if echo "$line" | grep -E 'property +ShellScreen +screen' >/dev/null; then
hasScreen=true
fi
fi
if [ "$inLauncherProvider" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
if echo "$line" | grep -E 'property +var +launcher: +null' >/dev/null; then
hasLauncher=true
fi
if echo "$line" | grep -E 'property +string +name: +".*"' >/dev/null; then
hasName=true
fi
fi
if [ "$inMain" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
fi
if [ "$inPanel" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
if echo "$line" | grep -E 'readonly +property +var +geometryPlaceholder:' >/dev/null; then
hasGeometryPlaceholder=true
fi
if echo "$line" | grep -E 'readonly +property +bool +allowAttach:' >/dev/null; then
hasAllowAttach=true
fi
fi
if [ "$inSettings" = true ]; then
if echo "$line" | grep -E 'property +var +pluginApi: +null' >/dev/null; then
hasPluginApi=true
fi
fi
line_index=$((line_index + 1))
fi
done <<<"$diff_changes"
# Print any required properties not printed on a new file found.
print_required_properties
if [[ "$issues" -ne 0 ]]; then
gh pr comment "$PR_NUMBER" --body "$comment_body"
fi