smith-ai-lab/smith-check

smith check, smith fmt et smith lint : vérification d'un projet avant validation, formatage avec .clang-format, clang-tidy avec .clang-tidy, et sur les fichiers .smith. À charger avant de valider, en cas d'échec d'une vérification, ou sur « le code doit être formaté avec clang-format » et les résultats de clang-tidy.

Qu'est-ce que smith-check ?

Cette compétence offre un ensemble complet d'outils de vérification et de formatage de code pour les projets utilisant le système de construction `smith`. Elle intègre `clang-format`, `clang-tidy` et `clangd` directement dans `smith`, garantissant un formatage et une analyse cohérents sur toutes les machines. La compétence couvre le formatage (fmt), l'analyse statique (lint), la vérification de la documentation (docs), les tests (test), la preuve formelle (prove) et une commande `check` qui exécute toutes ces étapes séquentiellement sans s'arrêter en cas d'échec. Elle est conçue pour être utilisée avant chaque commit afin de maintenir la qualité du code, et ses interfaces en ligne de commande sont `smith fmt`, `smith lint`, `smith check`, `smith docs`, `smith test` et `smith prove`. La compétence gère à la fois les fichiers C/C++/Objective-C standard et les fichiers `.smith` spécifiques au projet, avec une logique spéciale pour ces derniers. Elle supporte l'exécution sur des fichiers ou dossiers individuels, fournit un cache incremental pour `lint`, et offre des options comme `--dump-config` pour exporter les configurations par défaut de `smith` lorsqu'un projet ne définit pas les siennes.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/smith-ai-lab/smith/tree/HEAD/.agents/skills/smith-check

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

smith check, fmt, lint et lsp

smith fmt, smith lint et smith lsp sont clang-format, clang-tidy et clangd, liés dans smith depuis le même LLVM que le compilateur, de sorte que chaque machine formate et analyse de la même manière.

Sur le projet : sans arguments

Les verbes signifient la même chose dans chaque projet et lisent ce que son build.c déclare ; un projet n'écrit aucune tâche pour eux.

  • smith fmt réécrit chaque fichier C, C++, Objective-C et .smith que git voit (suivi, et non suivi mais non ignoré ; .c .h .m .mm .cpp .cc .cxx .hpp .hh .smith .metal) selon .clang-format (un fichier .metal est formaté en C++, le langage que clang-format donne à une extension qu'il ne connaît pas). smith fmt --dry-run (ou -n, avec --Werror ou -i) et smith lint --quiet sont aussi les formes du projet : options seules, sans noms de fichiers, donc ils n'attendent jamais l'entrée standard ; toute autre option, ou un nom de fichier, en fait les outils (smith fmt --assume-filename=x.c lit l'entrée standard). Un fichier nommé dans .clang-format-ignore (clang-format le lit lui-même : un parser.c généré, une fixture) est laissé tranquille. En dehors d'un dépôt git, il dit de nommer les fichiers (smith fmt -i <fichiers>).
  • smith lint construit ce que les compilations lisent (en-têtes générés), puis exécute clang-tidy avec .clang-tidy sur les sources propres du projet parmi les compilations de la construction (smith_object, et smith_compile_command pour les sources que la construction ne compile jamais), côte à côte. Pas .smith/, les sorties build/ ou les paquets. Chaque source .smith est analysée comme smith lint x.smith -- <flags> le fait : celles de la construction avec leur propre commande de compilation, et chaque autre fichier .smith que git voit avec la commande de compilation la plus proche, sauf ce que .clang-format-ignore nomme (la seule liste de fichiers qui ne sont pas des sources ordinaires : entrées de test, fixtures délibérément erronées, fichiers générés et copiés ; smith fmt la lit aussi, donc il n'y a pas de deuxième liste). Un résultat échoue à l'analyse ; sa dernière ligne dit linted N fichiers (smith check : lint ok: N fichiers), et un projet avec des sources .smith qui n'en analyse aucune échoue. Un .clang-tidy dans un dossier (comme InheritParentConfig: true avec d'autres vérifications) s'y applique.
  • smith lint est incrémental : le résultat de clang-tidy pour un fichier est mis en cache sous ~/.cache/smith/lint et rejoué tant que le fichier, ce qu'il inclut (pour un fichier .smith, aussi les en-têtes générés des modules qu'il importe), son .clang-tidy et smith sont inchangés, donc la dernière ligne lit smith lint : analysés 180 fichiers (3 exécutés, 177 en cache, 1,2 s) et un arbre inchangé n'exécute clang-tidy sur aucun fichier. SMITH_LINT_CACHE=0 le désactive, SMITH_LINT_CACHE=why dit pourquoi un fichier a été exécuté, smith cache clean lint le vide. Un fichier dont clang-tidy échoue est nommé dans les dernières lignes (smith lint : c.c : terminé avec le statut 1, ou a été tué par le signal 9, ce qui n'affiche rien de propre) et à la fin de sa propre sortie.
  • smith lint --changed[=<ref>] analyse seulement les fichiers modifiés depuis la base de fusion avec <ref> (par défaut : la branche amont, sinon la branche de origin/HEAD ou origin/main, jamais une main locale ; aucun d'eux n'est une erreur nommant --changed=<ref> ; la ligne qu'il affiche nomme la base ; les modifications et les fichiers non suivis comptent) et les fichiers qui les incluent ou les importent ; un .clang-tidy, fichier de construction, shim/ ou patches/ modifié sélectionne chaque fichier, et rien d'affecté le dit ainsi et réussit. De plus, il ne construit que ce que ces fichiers attendent. smith lint simple analyse tout (CI). Un fichier qui attend un paquet que le réseau ne fournit pas (l'analyseur tree-sitter dans un sandbox cloud) est ignoré par son nom (smith lint : ignoré runtime/tree_sitter_data.c : l'analyseur tree-sitter qu'il intégre ne peut pas être récupéré (<url>)) et le reste est analysé ; CI (CI ou SMITH_PRIORITY=ci) échoue à la place. smith lint FICHIER dans un projet pas encore construit (pas de compile_commands.json) s'arrête et dit d'exécuter smith build smith_needs une fois, plutôt que de signaler les en-têtes générés manquants comme des erreurs.
  • smith docs vérifie knowledge/ et les compétences (smith-docs).
  • smith check exécute fmt (dry-run de clang-format), docs, lint, test et prove, dans cet ordre, et ne s'arrête pas en cas d'échec : chaque partie affiche une ligne, smith check: <partie> ok: <détail> (<n> s mur, <n> s cpu) ou ÉCHEC (statut N) avec un extrait limité de l'échec et le chemin du journal complet (.smith/log/<partie>.log ; la sortie d'une partie réussie s'y trouve aussi ; smith check -v affiche tout au fur et à mesure), puis smith check: promesses: N (ce que smith croit, à partir d'une construction par défaut qu'il effectue si nécessaire), et la dernière ligne est smith check: ok ou smith check: échec: <parties> ; le code de sortie est 1 quand l'une d'elles a échoué. La ligne prove dit la couverture, smith check: prove ok (4 sur 23 fonctions): ... (fonctions avec un contrat propre, du projet ; 0 sur N fonctions quand il n'y a rien à prouver, ce qui est un succès ; rien n'échoue sur une faible couverture). Chaque ligne de partie se termine par son temps mur et CPU ((91,2 s mur, 480,1 s cpu) : CPU est le temps utilisateur plus système, de la partie et des processus qu'elle a attendus). Il ne prend pas d'arguments à part les options -D et -v. Sur un hôte qui n'est pas macOS, il exécute les tests avec --skip-macos et le dit (les tests spécifiques à macOS ne sont pas exécutés sur cet hôte). smith test se termine par un tableau des tâches de la construction (étapes .smith/task/<nom>, comme les propres test-<nom> de smith), les plus lentes en premier : secondes mur, CPU et système et le nombre de processus smith que chacune a démarrés (SMITH_START_LOG, que smith ajoute lorsque main commence ; une tâche qui efface l'environnement n'est pas comptée) ; les huit plus lentes, chaque tâche avec smith check -v ou SMITH_ACCOUNT=all, aucune avec SMITH_ACCOUNT=no. Les tâches sont exécutées via smith --smith-account <fichier> <nom> <commande...>, qui écrit la ligne.
  • Les fichiers .smith dans la nouvelle syntaxe ne sont pas du ressort de clang-format (#1890, #1886, #2040) : smith fmt envoie un fichier .smith au propre formateur de smith (front::format) sauf s'il est dans la syntaxe actuelle (une ligne commence par une forme que seules la syntaxe actuelle ou C possèdent, l'analyseur actuel le lit sans erreur, ou sa première erreur dans la nouvelle syntaxe a un correctif, comme un commentaire //) ou a une erreur d'analyse et aucune ligne que seule la nouvelle syntaxe a (fn, let, pub, #) : un seul style et pas de .clang-format pour lui (toute indentation cohérente sort à 4 espaces, une instruction par ligne, commentaires # conservés). Un fichier en nouvelle syntaxe avec une erreur d'analyse est signalé par chemin:ligne:colonne: message, laissé octet pour octet tel quel (même avec --dry-run) et fait échouer smith fmt avec le code 1 : il n'est jamais envoyé à clang-format, qui le déformerait. Il est idempotent, respecte .clang-format-ignore, et --dry-run / -n nomme les fichiers qui changeraient (chemin: serait formaté) sans écrire. Un fichier .smith dans la syntaxe actuelle (et chaque .c) reste du ressort de clang-format jusqu'à ce que le basculement (#1631) supprime ce recours. Testé par tests/fmt_smith_test.smith.
  • smith fmt FICHIER refuse un fichier dont l'extension n'est pas l'une de celles-ci (un .sh, un .md), avec une erreur qui nomme le fichier et n'écrit rien, puisque clang-format le lirait comme du C et le corromprait ; --assume-filename=x.c dit ce qu'il est.
  • Avant de valider : smith fmt, puis smith check.
  • Une tâche personnalisée (une vérification personnalisée, un générateur) est smith_task dans build.c et s'exécute avec smith build <tâche> ; aucune tâche ou alias ne peut être nommé fmt, lint, docs, prove, check, run ou test. smith build check et les autres noms de verbes sont refusés : utilisez le verbe.

Sur les fichiers : avec arguments

smith lint DOSSIER (un dossier parmi les arguments) analyse les sources C, C++, Objective-C et .smith sous celui-ci que git voit et que .clang-format-ignore ne nomme pas, comme l'analyse du projet (pas d'en-têtes, qui sont lues via leurs sources) ; smith lint front -- <flags> et smith lint front/ main.c se mélangent avec des fichiers. Un dossier sans telle source est une erreur.

L'analyseur de clang-tidy (clang-analyzer-*) lit smith_requires, smith_ensures, smith_invariant et smith_assert de <smith/contract.h> comme des hypothèses (target::static_analyzer), donc un index qu'un contrat borne n'est pas signalé par clang-analyzer-security.ArrayBound.

Le .clang-tidy par défaut de smith désactive deux vérifications de l'analyseur qui étaient du bruit (sur game, learner et smith : 546 sur 616 résultats) : clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling (chaque memcpy) et clang-analyzer-optin.performance.Padding. Réactivez-en une dans le propre .clang-tidy du projet (smith lint --dump-config > .clang-tidy écrit le fichier effectif) en supprimant sa ligne -clang-analyzer-....

smith lint --fix FICHIER.smith... (pas de --) applique les correctifs que le propre front-end de smith porte dans ses erreurs d'analyse (une forme ancienne ou de style C avec son orthographe smith : les modifications d'un correctif sont appliquées ensemble ou pas du tout, un correctif qui chevauche est ignoré, et un fichier est analysé à nouveau jusqu'à ce que rien ne s'applique, au plus 16 passages) et affiche chemin: N correctifs appliqués ; une deuxième exécution affiche 0 correctifs appliqués. Il lit uniquement les fichiers .smith et nécessite le smith complet. Avec -- <flags>, c'est le --fix de clang-tidy, ci-dessus. Aucune erreur d'analyse ne porte encore de correctif : les formes anciennes obtiennent leur ticket par ticket (#1428).

smith lint FICHIER ajoute --extra-arg=-I pour build/<os>/front-project/.smith/include quand ce dossier existe (les modules front s'importent mutuellement via lui), et sur un hôte qui n'est pas macOS affiche une ligne : CI analyse sur un Mac, où u64 est unsigned long long et usize est unsigned long, donc (U64)(i + 1) avec un usize est un résultat bugprone-misplaced-widening-cast uniquement là ; corrigez un tel cast en écrivant (U64)i + 1.

Avec des arguments, ce sont les outils : smith fmt main.c réécrit le fichier sur place (clang-format l'afficherait ; smith ajoute -i quand vous nommez des fichiers et qu'aucune option ne choisit un autre mode : -n, --dry-run, --lines, --assume-filename conservent le sens de clang-format, et smith fmt --assume-filename=x.c < x.c affiche le résultat), smith fmt --dry-run --Werror main.c, smith lint --quiet main.c -- <flags>, smith lsp --check=main.c. Le .clang-format et .clang-tidy du projet s'appliquent. Un smith stage0 exécute les outils de Homebrew, ou $SMITH_CLANG_FORMAT, $SMITH_CLANG_TIDY, $SMITH_CLANGD.

Les valeurs par défaut de smith, là où un projet n'a pas de fichier (problème #43). Un projet sans .clang-format (ou _clang-format) et sans .clang-tidy, recherchés à partir du dossier de chaque fichier et vers le haut comme le font clang-format et clang-tidy, est formaté et analysé avec ceux de smith, intégrés dans smith (les fichiers que smith new écrit aujourd'hui) ; il n'y a rien à écrire. Un fichier dans le projet remplace la totalité de ceux de smith, jamais fusionnée, et un --style (ou --fallback-style), --config ou --config-file explicite l'emporte. Avec l'entrée standard, --assume-filename nomme où chercher. Nommer des fichiers avec et sans fichier de projet dans une seule commande fonctionne (smith exécute le second type comme un autre processus). smith fmt --dump-config > .clang-format et smith lint --dump-config > .clang-tidy affichent la configuration effective (celle du projet, sinon celle de smith), donc un projet s'approprie les valeurs par défaut en les exportant et modifie ce qu'il veut ; les valeurs par défaut changent rarement et intentionnellement, donc un projet qui les veut fixes les exporte. smith écrit sa copie dans $XDG_DATA_HOME/smith/defaults/ (sinon ~/.local/share/...). smith cc n'est jamais affecté : il reste un pur passage.

Fichiers .smith

smith fmt x.smith (et -i, --dry-run, l'entrée standard avec --assume-filename=x.smith) formate un fichier .smith en C, avec ses chemins ::, les lignes module a::b; et import a::b as x; et import <sys/wait.h>; conservées intégralement ; smith fmt sans arguments formate aussi les fichiers .smith du projet (git les voit). import et module à l'intérieur d'une fonction sont des noms, comme en C. Nécessite un smith dont clang-format a le correctif .smith (un stage0 exécute celui de Homebrew, qui lit .smith comme du C++ et donc interprète mal les noms C qui sont des mots-clés C++, comme throw). clangd formate les fichiers .smith de la même manière.

smith lint x.smith -- <flags> (clang-tidy, avec le .clang-tidy du projet) analyse un fichier .smith comme smith cc le lit (-x c, et -std=gnu2y sauf si vous nommez un standard ; la commande propre d'une base de données de compilation est utilisée telle quelle) et signale comme la source est écrite : résultats, notes et correctifs aux lignes et colonnes du texte .smith, avec les noms tels qu'écrits (area et Box dans le module, box::area là où il est importé, jamais geometry_box_area). readability-identifier-naming juge le nom écrit des noms au niveau du fichier d'un module, donc les règles du modèle (snake_case pour les fonctions et variables, PascalCase pour les types) s'appliquent à area et Box, et --fix réécrit le jeton dans la source ; les types dimensionnés (U32, I32), les copies d'abaissement des prototypes et les en-têtes que smith build écrit ne sont jamais signalés. Un résultat concernant une exportation est signalé dans le fichier du module, pas dans chaque importateur, et un correctif là ne renomme pas les importateurs. Les autres vérifications montrent les noms écrits dans leurs messages, mais une vérification qui compare le nom lui-même (une vérification de longueur ou de nom réservé, par exemple) lit encore celui abaissé. Nécessite un smith dont le clang a le crochet de jeton (smith cc --smith-which x.smith dit token-hook yes) ; un stage0 exécute le clang-tidy de Homebrew, qui ne peut pas lire .smith.

Appartient aussi à cette famille : smith-check-lints.

Skills associés