batch-script-progress

Par github · awesome-copilot

Concevez et vérifiez la sortie à l'exécution lors de la création ou modification de scripts Python, PowerShell ou Node.js traitant plusieurs fichiers, enregistrements ou requêtes API. À utiliser pour les scripts batch, les opérations en masse, les boucles longues silencieuses, les rapports de progression, les échecs par élément, les comptes finaux, la séparation stdout, ou la cohérence des codes de sortie. Non destiné aux barres de progression UI, à l'infrastructure de monitoring, ni aux mises à jour de progression dans la conversation IA.

npx skills add https://github.com/github/awesome-copilot --skill batch-script-progress

Progression des scripts batch

Rendre les scripts batch générés observables pendant leur exécution, sans modifier leur contrat de traitement. Concevoir ensemble les sorties de démarrage, progression périodique, échec par élément et résumé final, ainsi que les flux de résultats et le statut de sortie. Une bibliothèque de barre de progression seule n'établit pas ce contrat.

1. Corriger le contrat existant

Lire le script, les appelants et les tests proches avant de modifier. Identifier :

  • Unité d'entrée, total connu ou inconnu, et si l'énumération est lazy.
  • Format stdout existant et ses consommateurs, version runtime, et exécution interactive versus redirigée.
  • Politique de continuer-en-cas-d'erreur ou fail-fast, règles de retry, règles de skip, limites de transaction et comportement d'annulation.
  • Codes de sortie existants et ce que les appelants considèrent comme un succès.

Préserver ces décisions. Ne pas ajouter de retries, parallélisme, dépendances ou nouvelle politique d'échec juste pour ajouter une sortie de progression. Si les défaillances partielles retournent actuellement zéro, rapporter l'outcome partiel honnêtement tout en gardant ce contrat de sortie. Si le contrat est manquant ou contradictoire, demander la décision qui change le comportement ; ne pas la prendre silencieusement.

2. Définir le contrat de sortie avant l'implémentation

Choisir un vocabulaire et des champs petits et stables, en réutilisant le logger du repository quand approprié :

  • Démarrage : nom de l'opération, total ou inconnu explicite, et compteurs initiaux. Émettre avant l'énumération coûteuse ; la découverte elle-même peut avoir besoin de progression.
  • Progression : traités, réussis, échoués, ignorés, total ou inconnu, et temps écoulé. Ajouter un identifiant d'élément courant assaini uniquement si utile.
  • Échec d'élément : identifiant sûr, catégorie d'échec ou raison assainie, et si le traitement continuera. Émettre quand observé, indépendamment de l'intervalle de progression normal.
  • Résumé : complété, partiel, échoué ou annulé ; compteurs finaux ; temps écoulé ; nombre connu d'éléments non traités si disponible ; et le statut de sortie requis par le contrat existant.

Définir traités = réussis + échoués + ignorés pour les éléments ayant atteint un outcome terminal. Garder séparés les éléments en cours et non démarrés. Compter chaque élément une fois ; les tentatives de retry ne sont pas des éléments traités supplémentaires. Ne pas marquer un élément comme réussi avant son commit, écriture ou accusé de réception requis. Si une transaction revient en arrière, rapporter le travail annulé plutôt que de prétendre au succès durable.

Pour un total inconnu, rapporter les comptages sans pourcentage fabriqué, ETA ou compte restant. Ne pas matérialiser un flux juste pour le compter. Pour zéro élément, émettre démarrage et résumé avec comptages zéro ; ne jamais diviser par zéro.

3. Choisir les flux de sortie et la cadence

Réserver stdout au résultat machine-lisible établi, aux objets pipeline ou au protocole. Mettre la progression et les diagnostics sur un canal séparé ; stderr est la valeur par défaut portable pour les scripts CLI autonomes. La sortie stderr seule n'implique pas d'échec : les appelants doivent utiliser le code de sortie convenu et le contrat de résultat. Vérifier les appelants qui traitent tout stderr comme un échec avant de modifier leur sortie. Si stdout est réservé et stderr incompatible, utiliser un logger ou sink compatible existant uniquement si l'appelant le supporte déjà. Ne pas déplacer la progression vers stdout ou un autre flux avec des sémantiques modifiées. Si aucun canal compatible n'existe, s'arrêter et demander si le contrat de sortie peut changer, ou rapporter que la progression ne peut pas être ajoutée en toute sécurité.

Utiliser une cadence bornée, comme tous les nombres d'éléments configurés ou l'intervalle écoulé, plutôt que de logger sans condition chaque élément. Émettre démarrage, échecs et résumé indépendamment de cette cadence. Préserver les enregistrements d'audit requis par élément séparément. Éviter les listes d'échecs non bornées en mémoire et les stack traces répétées. Redacter les credentials, paramètres de requête, données personnelles et chemins sensibles avant le formatage ; ne pas dumper les exceptions brutes ou les enregistrements d'entrée entiers par défaut.

Utiliser le temps monotone pour les intervalles et durées. S'assurer que la sortie est purgée ou drainée pour que les notifications arrivent avant la sortie. Utiliser des enregistrements simples délimités par newline sous redirection ; activer la réécriture de terminal ou couleurs uniquement pour un TTY approprié. Garder les significations des champs de log cohérentes entre les langages, pas nécessairement leurs formatages exacts ou bibliothèques.

Une vérification de temps à la fin d'une boucle ne peut pas émettre pendant qu'un élément bloque. Pour un élément long, utiliser les callbacks de progression existants, notifications d'étape, ou un heartbeat intégré en toute sécurité où le runtime le permet. Un timer Node.js ne peut pas fonctionner à travers le blocage d'event-loop synchrone ; un affichage de progression PowerShell n'est pas un log durable. Si la progression mid-item ne peut pas être ajoutée sans changer les sémantiques d'exécution, émettre l'étape courante avant qu'elle ne commence et divulguer l'écart de notification. Ne pas promettre un heartbeat périodique que l'implémentation ne peut pas livrer.

4. Implémenter le plus petit changement compatible

Lire les notes de langage et exemples sûrs pour le runtime sélectionné. Les exemples sont des sondes de contrat de sortie exécutables, pas des processeurs production ; adapter leur émetteur et comptabilité au code existant plutôt que de copier leur politique d'échec.

Garder le reporting séparé des décisions de traitement. Dans le code concurrent, sérialiser le reporting à travers le coordinateur et compter les outcomes complétés, pas les soumissions. Lors d'une défaillance traitée ou d'une annulation, tenter un dernier résumé et préserver l'outcome original ; une erreur d'écriture de résumé ne doit pas remplacer l'exception de traitement originale. Ne pas masquer l'annulation comme un échec ordinaire d'élément. Pour l'annulation gérée par l'hôte, incluant les arrêts d'hôte PowerShell, préserver le comportement d'hôte existant ; ne pas convertir les exceptions stop en échecs d'élément ou promettre un résumé final après la terminaison de l'hôte. Utiliser finally pour le nettoyage applicable, mais vérifier le chemin d'annulation réel dans l'hôte supporté quand l'annulation gracieuse fait partie du contrat.

Ne pas forcer la terminaison réussie à livrer la sortie bufferisée. En Node.js, préférer définir process.exitCode et drainer les écritures plutôt qu'un process.exit() immédiat. Respecter les sémantiques d'hôte/bibliothèque existantes en PowerShell : une fonction réutilisable ne doit pas quitter son appelant. La terminaison forcée, les crashs de processus et les pipes de sortie cassés peuvent empêcher le reporting final ; ne pas affirmer le contraire.

5. Vérifier avant de rapporter l'achèvement

Lire les cas de vérification, puis exécuter des tests ciblés pour le script modifié avec des fixtures inoffensives. Capturer stdout et stderr séparément et vérifier le statut de sortie réel. Vérifier l'ordre démarrage/progression, compteurs monotones, échecs assainis, exactement un résumé sur les chemins supportés, et contenus de résultats inchangés et politique de traitement.

Prouver la vivacité en lisant la sortie du processus enfant pendant qu'il fonctionne encore, pas en examinant la sortie collectée après la sortie. Vérifier les comportements terminal et redirigé quand tous deux sont supportés. Une pause contrôlée après un événement de progression est une sonde déterministe utile : recevoir l'événement, confirmer que l'enfant n'a pas quitté, puis le libérer. Garder telles les gates dans les fixtures de test inoffensives ou le harnais de test ; ne pas ajouter d'attentes stdin, sleeps ou hooks d'annulation au traitement production normal uniquement pour faire passer un test. Préférer une limite de traitement callback existante ou injectable. Si aucune couture déterministe sûre n'existe, tester le chemin réel uniquement avec des entrées inoffensives ou rapporter la vivacité comme non vérifiée. Un watchdog peut échouer le test ; il ne doit pas fabriquer un résultat réussi.

Le vérificateur multilingue fourni exécute les sondes Python, PowerShell et Node.js avec des cas normal, défaillance partielle, défaillance partielle préservée exit-zéro, vide, total inconnu, fail-fast, annulation simulée et sortie en direct. Il vérifie les sondes uniquement ; il ne prouve pas qu'un script généré arbitraire ou une sélection automatique de skill fonctionne.

L'exécuter depuis ce dossier skill avec Node.js 20 ou ultérieur :

node tests/verify-examples.mjs

Il requiert aussi Python 3.9 ou ultérieur et PowerShell 5.1 ou ultérieur. Voir les notes de langage pour les surcharges exécutables. Les runtimes manquants sont des défaillances, pas une couverture silencieusement ignorée.

Livrables

Retourner le script modifié, son contrat de sortie/sortie, et résultats de vérification ciblés. Distinguer les tests exécutés de l'inspection et des cas non exécutés. Ne pas appeler le script vérifié simplement parce qu'il imprime une barre de progression ou que les métadonnées du skill passent la validation.

Pièges

  • Compter avant de logger peut faire que la découverte consomme silencieusement un flux entier.
  • Écrire le statut avec PowerShell Write-Output ajoute des chaînes au pipeline de succès.
  • Mesurer uniquement la sortie bufferisée après sortie ne peut pas prouver la visibilité de la progression.
  • Un message final disant complété masque la défaillance partielle à moins que l'outcome et les compteurs l'expliquent.
  • finally n'est pas une garantie de reporting après terminaison forcée.

Skills similaires