mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
tools: run additional linters
This commit is contained in:
parent
e185465836
commit
a5a047f608
12 changed files with 124 additions and 36 deletions
1
justfile
1
justfile
|
@ -79,5 +79,6 @@ lint-format:
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
shopt -s globstar
|
shopt -s globstar
|
||||||
clang-format -i **/*.{c,h}
|
clang-format -i **/*.{c,h}
|
||||||
|
tools/additional_lint
|
||||||
|
|
||||||
lint: (lint-imports) (lint-format)
|
lint: (lint-imports) (lint-format)
|
||||||
|
|
83
tools/additional_lint
Executable file
83
tools/additional_lint
Executable file
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
from collections.abc import Callable, Iterable
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from shared.common import DATA_DIR, REPO_DIR, SRC_DIR, TOOLS_DIR
|
||||||
|
|
||||||
|
EXTENSIONS = [
|
||||||
|
"Dockerfile",
|
||||||
|
".h",
|
||||||
|
".c",
|
||||||
|
".build",
|
||||||
|
".ninja",
|
||||||
|
".py",
|
||||||
|
".cs",
|
||||||
|
".xaml",
|
||||||
|
".csproj",
|
||||||
|
".txt",
|
||||||
|
".rc",
|
||||||
|
".glsl",
|
||||||
|
".md",
|
||||||
|
".json",
|
||||||
|
".json5",
|
||||||
|
"Dockerfile",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LintWarning:
|
||||||
|
path: Path
|
||||||
|
message: str
|
||||||
|
line: int | None = None
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
prefix = str(self.path.relative_to(REPO_DIR))
|
||||||
|
if self.line is not None:
|
||||||
|
prefix += f":{self.line}"
|
||||||
|
return f"{prefix}: {self.message}"
|
||||||
|
|
||||||
|
|
||||||
|
def get_files() -> Iterable[Path]:
|
||||||
|
for root_dir in (DATA_DIR, SRC_DIR, TOOLS_DIR):
|
||||||
|
for path in root_dir.rglob("**/*"):
|
||||||
|
if path.is_file() and path.suffix in EXTENSIONS:
|
||||||
|
yield path
|
||||||
|
|
||||||
|
|
||||||
|
def lint_newlines(path: Path) -> Iterable[LintWarning]:
|
||||||
|
text = path.read_text()
|
||||||
|
if text and not text.endswith("\n"):
|
||||||
|
yield LintWarning(path, "missing newline character at end of file")
|
||||||
|
|
||||||
|
|
||||||
|
def lint_trailing_whitespace(path: Path) -> Iterable[LintWarning]:
|
||||||
|
for i, line in enumerate(path.open("r"), 1):
|
||||||
|
if line.rstrip("\n").endswith(" "):
|
||||||
|
yield LintWarning(path, "trailing whitespace", line=i)
|
||||||
|
|
||||||
|
|
||||||
|
LINTERS: list[Callable[[], Iterable[LintWarning]]] = [
|
||||||
|
lint_newlines,
|
||||||
|
lint_trailing_whitespace,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
files = get_files()
|
||||||
|
|
||||||
|
exit_code = 0
|
||||||
|
for file in files:
|
||||||
|
for linter in LINTERS:
|
||||||
|
for lint_warning in linter(file):
|
||||||
|
print(
|
||||||
|
str(lint_warning),
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
exit_code = 1
|
||||||
|
|
||||||
|
exit(exit_code)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -1,11 +1,11 @@
|
||||||
<UserControl
|
<UserControl
|
||||||
x:Class="TR1X_ConfigTool.Controls.CategoryControl"
|
x:Class="TR1X_ConfigTool.Controls.CategoryControl"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:controls="clr-namespace:TR1X_ConfigTool.Controls"
|
xmlns:controls="clr-namespace:TR1X_ConfigTool.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800">
|
d:DesignWidth="800">
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<Window
|
<Window
|
||||||
x:Class="TR1X_ConfigTool.MainWindow"
|
x:Class="TR1X_ConfigTool.MainWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
Height="575"
|
Height="575"
|
||||||
MinWidth="620"
|
MinWidth="620"
|
||||||
MinHeight="355">
|
MinHeight="355">
|
||||||
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
<utils:BoolToVisibilityConverter
|
<utils:BoolToVisibilityConverter
|
||||||
|
@ -35,22 +35,22 @@
|
||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
|
|
||||||
<Window.InputBindings>
|
<Window.InputBindings>
|
||||||
<utils:RelayKeyBinding
|
<utils:RelayKeyBinding
|
||||||
CommandBinding="{Binding OpenCommand}"
|
CommandBinding="{Binding OpenCommand}"
|
||||||
Modifiers="Ctrl"
|
Modifiers="Ctrl"
|
||||||
Key="O" />
|
Key="O" />
|
||||||
<utils:RelayKeyBinding
|
<utils:RelayKeyBinding
|
||||||
CommandBinding="{Binding ReloadCommand}"
|
CommandBinding="{Binding ReloadCommand}"
|
||||||
Key="F5" />
|
Key="F5" />
|
||||||
<utils:RelayKeyBinding
|
<utils:RelayKeyBinding
|
||||||
CommandBinding="{Binding SaveCommand}"
|
CommandBinding="{Binding SaveCommand}"
|
||||||
Modifiers="Ctrl"
|
Modifiers="Ctrl"
|
||||||
Key="S" />
|
Key="S" />
|
||||||
<utils:RelayKeyBinding
|
<utils:RelayKeyBinding
|
||||||
CommandBinding="{Binding SaveAsCommand}"
|
CommandBinding="{Binding SaveAsCommand}"
|
||||||
Modifiers="Ctrl+Alt"
|
Modifiers="Ctrl+Alt"
|
||||||
Key="S" />
|
Key="S" />
|
||||||
<utils:RelayKeyBinding
|
<utils:RelayKeyBinding
|
||||||
CommandBinding="{Binding GitHubCommand}"
|
CommandBinding="{Binding GitHubCommand}"
|
||||||
Key="F11" />
|
Key="F11" />
|
||||||
</Window.InputBindings>
|
</Window.InputBindings>
|
||||||
|
@ -121,7 +121,7 @@
|
||||||
Visibility="{Binding IsEditorActive, Converter={StaticResource BoolToHiddenConverter}}"/>
|
Visibility="{Binding IsEditorActive, Converter={StaticResource BoolToHiddenConverter}}"/>
|
||||||
<StatusBarItem>
|
<StatusBarItem>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{Binding IsEditorDirty, Converter={utils:ConditionalViewTextConverter TrueValue='label_unsaved', FalseValue='label_saved'}}"
|
Text="{Binding IsEditorDirty, Converter={utils:ConditionalViewTextConverter TrueValue='label_unsaved', FalseValue='label_saved'}}"
|
||||||
Foreground="{Binding IsEditorDirty, Converter={utils:ConditionalMarkupConverter TrueValue='DarkRed', FalseValue='DarkGreen'}}"
|
Foreground="{Binding IsEditorDirty, Converter={utils:ConditionalMarkupConverter TrueValue='DarkRed', FalseValue='DarkGreen'}}"
|
||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
Visibility="{Binding IsEditorActive, Converter={StaticResource BoolToHiddenConverter}}"/>
|
Visibility="{Binding IsEditorActive, Converter={StaticResource BoolToHiddenConverter}}"/>
|
||||||
|
@ -134,7 +134,7 @@
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TabControl
|
<TabControl
|
||||||
Margin="0,0,0,7"
|
Margin="0,0,0,7"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
|
@ -185,7 +185,7 @@
|
||||||
Style="{StaticResource ButtonStyle}"/>
|
Style="{StaticResource ButtonStyle}"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="7,0,0,0"
|
Margin="7,0,0,0"
|
||||||
Command="{Binding LaunchGameCommand}"
|
Command="{Binding LaunchGameCommand}"
|
||||||
Content="{Binding ViewText[command_launch_game]}"
|
Content="{Binding ViewText[command_launch_game]}"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<UserControl
|
<UserControl
|
||||||
x:Class="TR1X_ConfigTool.Controls.NumericUpDown"
|
x:Class="TR1X_ConfigTool.Controls.NumericUpDown"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:utils="clr-namespace:TR1X_ConfigTool.Utils"
|
xmlns:utils="clr-namespace:TR1X_ConfigTool.Utils"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="25"
|
d:DesignHeight="25"
|
||||||
d:DesignWidth="140">
|
d:DesignWidth="140">
|
||||||
|
|
||||||
|
@ -34,11 +34,11 @@
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBox
|
<TextBox
|
||||||
x:Name="_textBox"
|
x:Name="_textBox"
|
||||||
PreviewKeyDown="TextBox_PreviewKeyDown"
|
PreviewKeyDown="TextBox_PreviewKeyDown"
|
||||||
PreviewTextInput="TextBox_TextInput"
|
PreviewTextInput="TextBox_TextInput"
|
||||||
TextChanged="TextBox_TextChanged"
|
TextChanged="TextBox_TextChanged"
|
||||||
DataObject.Pasting="TextBox_Pasting"
|
DataObject.Pasting="TextBox_Pasting"
|
||||||
LostFocus="TextBox_LostFocus"
|
LostFocus="TextBox_LostFocus"
|
||||||
Grid.RowSpan="3"
|
Grid.RowSpan="3"
|
||||||
Style="{StaticResource NumericTextBoxStyle}">
|
Style="{StaticResource NumericTextBoxStyle}">
|
||||||
|
@ -70,13 +70,13 @@
|
||||||
Style="{StaticResource FlatRepeatButtonStyle}"/>
|
Style="{StaticResource FlatRepeatButtonStyle}"/>
|
||||||
|
|
||||||
<Border
|
<Border
|
||||||
Background="#666"
|
Background="#666"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.Row="1"/>
|
Grid.Row="1"/>
|
||||||
|
|
||||||
<RepeatButton
|
<RepeatButton
|
||||||
Command="{Binding Data.SpinDownCommand, Source={StaticResource controlProxy}}"
|
Command="{Binding Data.SpinDownCommand, Source={StaticResource controlProxy}}"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Content="..\Resources\arrow-down.png"
|
Content="..\Resources\arrow-down.png"
|
||||||
ToolTip="{Binding Data.ViewText[spinner_decrease], Source={StaticResource windowProxy}}"
|
ToolTip="{Binding Data.ViewText[spinner_decrease], Source={StaticResource windowProxy}}"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<UserControl
|
<UserControl
|
||||||
x:Class="TR1X_ConfigTool.Controls.PropertyControl"
|
x:Class="TR1X_ConfigTool.Controls.PropertyControl"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
@ -6,15 +6,15 @@
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:controls="clr-namespace:TR1X_ConfigTool.Controls"
|
xmlns:controls="clr-namespace:TR1X_ConfigTool.Controls"
|
||||||
xmlns:models="clr-namespace:TR1X_ConfigTool.Models"
|
xmlns:models="clr-namespace:TR1X_ConfigTool.Models"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800">
|
d:DesignWidth="800">
|
||||||
|
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{Binding Title}"
|
Text="{Binding Title}"
|
||||||
Style="{StaticResource PropertyTitleStyle}"/>
|
Style="{StaticResource PropertyTitleStyle}"/>
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{Binding Description}"
|
Text="{Binding Description}"
|
||||||
Style="{StaticResource PropertyDescriptionStyle}"/>
|
Style="{StaticResource PropertyDescriptionStyle}"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -81,7 +81,7 @@ public class Configuration
|
||||||
|
|
||||||
public void Read(string jsonPath)
|
public void Read(string jsonPath)
|
||||||
{
|
{
|
||||||
JObject externalData = File.Exists(jsonPath)
|
JObject externalData = File.Exists(jsonPath)
|
||||||
? JObject.Parse(File.ReadAllText(jsonPath))
|
? JObject.Parse(File.ReadAllText(jsonPath))
|
||||||
: new();
|
: new();
|
||||||
JObject activeData = new();
|
JObject activeData = new();
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace TR1X_ConfigTool.Models;
|
namespace TR1X_ConfigTool.Models;
|
||||||
|
|
||||||
public class EnumProperty : BaseProperty
|
public class EnumProperty : BaseProperty
|
||||||
{
|
{
|
||||||
public string EnumKey { get; set; }
|
public string EnumKey { get; set; }
|
||||||
|
|
||||||
private EnumOption _value;
|
private EnumOption _value;
|
||||||
|
|
||||||
public EnumOption Value
|
public EnumOption Value
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate
|
<ControlTemplate
|
||||||
TargetType="{x:Type RepeatButton}">
|
TargetType="{x:Type RepeatButton}">
|
||||||
<Border
|
<Border
|
||||||
Background="{TemplateBinding Background}"
|
Background="{TemplateBinding Background}"
|
||||||
Padding="0,2"
|
Padding="0,2"
|
||||||
BorderThickness="1,0,0,0"
|
BorderThickness="1,0,0,0"
|
||||||
|
|
|
@ -9,4 +9,4 @@ pkg-config = '/opt/local/bin/pkg-config'
|
||||||
system = 'darwin'
|
system = 'darwin'
|
||||||
cpu_family = 'x86_64'
|
cpu_family = 'x86_64'
|
||||||
cpu = 'x86_64'
|
cpu = 'x86_64'
|
||||||
endian = 'little'
|
endian = 'little'
|
||||||
|
|
6
tools/shared/common.py
Normal file
6
tools/shared/common.py
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
TOOLS_DIR = Path(__file__).parent.parent
|
||||||
|
REPO_DIR = TOOLS_DIR.parent
|
||||||
|
DATA_DIR = REPO_DIR / "src"
|
||||||
|
SRC_DIR = REPO_DIR / "src"
|
|
@ -5,9 +5,7 @@ from pathlib import Path
|
||||||
from shutil import which
|
from shutil import which
|
||||||
from subprocess import run
|
from subprocess import run
|
||||||
|
|
||||||
TOOLS_DIR = Path(__file__).parent
|
from shared.common import SRC_DIR
|
||||||
REPO_DIR = TOOLS_DIR.parent
|
|
||||||
SRC_PATH = REPO_DIR / "src"
|
|
||||||
|
|
||||||
|
|
||||||
def fix_imports(path: Path) -> None:
|
def fix_imports(path: Path) -> None:
|
||||||
|
@ -34,7 +32,7 @@ def custom_sort(source: list[str], forced_order: list[str]) -> list[str]:
|
||||||
|
|
||||||
def sort_imports(path: Path) -> None:
|
def sort_imports(path: Path) -> None:
|
||||||
source = path.read_text()
|
source = path.read_text()
|
||||||
rel_path = path.relative_to(SRC_PATH)
|
rel_path = path.relative_to(SRC_DIR)
|
||||||
own_include = str(rel_path.with_suffix(".h"))
|
own_include = str(rel_path.with_suffix(".h"))
|
||||||
own_include = {
|
own_include = {
|
||||||
# files headers of which are not a 1:1 match with their filename
|
# files headers of which are not a 1:1 match with their filename
|
||||||
|
@ -112,8 +110,8 @@ def main() -> None:
|
||||||
if not paths:
|
if not paths:
|
||||||
paths = sorted(
|
paths = sorted(
|
||||||
path
|
path
|
||||||
for path in SRC_PATH.glob("**/*.[ch]")
|
for path in SRC_DIR.glob("**/*.[ch]")
|
||||||
if path != SRC_PATH / "init.c"
|
if path != SRC_DIR / "init.c"
|
||||||
)
|
)
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue