3 Stimmen

Automatisch aktualisierte Header-Kommentare in C++

Dies ist eine der Kopfzeilen, die ich in WxWidgets gefunden habe, und ich mag sie. Ich frage mich, ob es eine Möglichkeit gibt, in alle meine Quelldateien einen Header wie diesen einzufügen und ihn automatisch aktualisiert zu halten? Er enthält zwei Eigenschaften von SVN, die mir bekannt sind.

/////////////////////////////////////////////////////////////////////////////
// Name:        <filename>.cpp
// Purpose:     
// Author:      <AuthorName>
// Modified by:
// Created:     $Date$
// RCS-ID:      $Id$
// Copyright:   (c) <Year> <AuthorName>
// Licence:     <licensetype>
/////////////////////////////////////////////////////////////////////////////

3voto

Jonathan Leffler Punkte 694013

Das hängt zum Teil davon ab, welches VCS Sie verwenden. Für meine eigene Arbeit verwendete ich bis 1999 SCCS, wechselte dann aber zu RCS, um Probleme mit dem Jahr 2000 zu vermeiden (das SCCS-Datumsformat verwendet zwei Ziffern für das Jahr, was ich inakzeptabel finde). Infolgedessen habe ich eine klare Vorstellung davon, wie man diese Systeme vernünftig nutzen kann. Irgendwo in SO habe ich bereits erörtert, was in meine Datei-Header gehört, aber es ist einfacher, eine Illustration zu finden als diese andere Antwort...

/*
@(#)File:           $RCSfile: stderr.c,v $
@(#)Version:        $Revision: 9.14 $
@(#)Last changed:   $Date: 2009/07/17 19:00:58 $
@(#)Purpose:        Error reporting routines
@(#)Author:         J Leffler
@(#)Copyright:      (C) JLSS 1988-91,1996-99,2001,2003,2005-09
@(#)Product:        :PRODUCT:
*/

Dies ist eine meiner ältesten Quelldateien - migriert von SCCS zu RCS. Das VCS (d.h. RCS) behält automatisch die Werte für $RCSfile$, $Revision$ und $Date$ bei. Ich habe ein Shell-Skript, das ein Perl-Skript ansteuert, um die Copyright-Daten zu pflegen; ich muss daran denken, es zu verwenden, wenn ich die Datei in einem bestimmten Jahr zum ersten Mal bearbeite. Ich habe mir noch nicht die Mühe gemacht, ein Filterskript zu erstellen, das nur die Copyright-Zeile hackt (was für mich eher ungewöhnlich ist - ich erstelle viele Skripte). Diese Datei ist in ihrem "unverteilten" Format; wenn ich sie mit einem Produkt verteile, wird das ':PRODUCT:'-Metaschlüsselwort erweitert, um das entsprechende Produkt zu benennen (durch meine Software zur Erstellung von Veröffentlichungen). Es ist klar, dass weder mein Name noch der Zweck der Datei besonders gepflegt werden müssen. (Nebenbei bemerkt bevorzuge ich immer noch die SCCS-Verwaltung von Schlüsselwörtern - die SCCS-Entsprechung von $RCSfile$ usw.)

Wenn das Versionskontrollsystem die Schlüsselwörter nicht unterstützt, ist es viel schwieriger zu entscheiden, wie solche Informationen zu behandeln sind. Die erste Regel lautet: "Kämpfe nicht gegen dein VCS". Kriegsgeschichte - wir haben versucht, das VCS zu bekämpfen, und es hat nicht funktioniert. Es war einmal vor langer Zeit (vor anderthalb Jahrzehnten), als das Unternehmen von SCCS auf Atria Clearcase (jetzt IBM Rational ClearCase) umstieg. ClearCase unterstützt nicht die Einbettung von Versionsinformationen in Quelldateien. Es unterstützt jedoch Checkin-Trigger. Wir haben einen Trigger geschrieben und implementiert, um sicherzustellen, dass die ClearCase-Versionsnummern in die Dateien eingebettet werden, wie es zuvor bei den SCCS-Versionsnummern der Fall war. Der Checkin-Trigger funktionierte einwandfrei; wir konnten uns die Datei innerhalb oder außerhalb der Ansicht ansehen und feststellen, zu welcher Version sie gehörte. Aber die Änderungen in den Versionsnummern machten den Zusammenführungscode kaputt - alle Zusammenführungen wurden zu manuellen Zusammenführungen, selbst wenn der einzige Konflikt in der Versionsnummer bestand. Das lag daran, dass wir das VCS bekämpften und es uns nicht gewinnen lassen wollte. Also haben wir den Checkin-Trigger schließlich aufgegeben.

Ich versuche immer noch herauszufinden, wie man die Versionsstempelung von Quelldateien mit einem modernen DVCS wie git handhabt. Es sieht so aus, als müsste ich mein gesamtes Versionssystem überarbeiten - wahrscheinlich als Hybrid, der sowohl SCCS und RCS (wie jetzt, obwohl der SCCS-Teil seit fast einem Jahrzehnt nicht mehr verwendet wird) als auch git umfasst.

Eine Theorie, die von vielen vertreten wird, besagt, dass man es vermeiden sollte, Metadaten in Quelldateien zu integrieren. Ich bin immer noch nicht ganz davon überzeugt, dass dies gut ist - ich denke, es ist hilfreich, den Ursprung einer Quelldatei zu sehen, selbst wenn sie aus ihrem ursprünglichen Kontext herausgelöst wurde (umbenannt, aus ihrem ursprünglichen Paket entfernt, verändert und in ein neues Produkt aufgenommen). Vielleicht muss ich mit diesem Standpunkt leben, wenn ich ein DVCS verwende.

Ich vertrete die Theorie, dass Metadaten in Dateien enthalten sein sollten, weil sie nicht immer in ihrem ursprünglichen Kontext verwendet werden und die Metadaten überleben und helfen können, ihren Ursprung zu identifizieren, selbst Jahrzehnte später. Wenn ich also eine Quellcode-Veröffentlichung erstelle, verwende ich meine Veröffentlichungssoftware, um die Produktinformationen automatisch einzutragen, wobei ich die Notationen :PRODUCT: usw. verwende, um zu markieren, was bearbeitet werden soll. Sie können dies bei der Arbeit sehen, wenn Sie eines der Pakete herunterladen, die ich zum IIUG (International Informix Users Group) Website. Ich würde SQLCMD als das wahrscheinlich größte und aktuellste Paket empfehlen - obwohl es dort schon seit Mitte der 90er Jahre und Version 23 oder so verfügbar ist (derzeit ist es Version 86.00).

Eines der größten Probleme, die ich mit Git habe, ist, dass fast alle meine Programme den Code in stderr.c und stderr.h verwenden. Es ist mir jedoch noch nicht klar, wie ich denselben Code in jedes der vielen Produkte, die ihn verwenden, einbauen kann, ohne ihn mehrfach zu pflegen. Dies ist bei weitem nicht das einzige Paar von Quelldateien, das ich unverändert in vielen verschiedenen Produkten verwende. Aber ich möchte nicht die gesamte Bibliothek mit jedem Produkt erstellen - die Bibliothek wäre größer als viele der Produkte, und ein bestimmtes Produkt verwendet nur ein paar Dateien aus der Bibliothek. ...Tja, eines Tages wird die Erleuchtung kommen...

Ich stimme nicht mit den Kommentaren überein, dass der Name der Datei keine Metadaten sind, die in der Datei gespeichert werden sollten. Ich denke, es lohnt sich, sie zu behalten - denn der Name kann sich ändern, während der Inhalt sich nicht ändert, und es ist einfacher zu sehen, woher die Datei stammt, wenn die Metadaten vorhanden sind. Natürlich können Böswillige die Metadaten manipulieren (oder entfernen) - aber das tun sie oft nicht.

2voto

C Pirate Punkte 456

Eine Möglichkeit wäre, einen Pre-Commit-Hook in Ihren Subversion-Server einzubauen, der überprüft, ob der Header existiert. Es gibt nichts, was Sie wirklich tun können, um sicherzustellen, dass er auf dem neuesten Stand ist, abgesehen von der Selbst- und Teamdisziplin; Sie könnten einige von ihnen automatisch überprüfen (z.B. Erstellt, Geändert von, etc.), aber Sie könnten Subversion-Eigenschaften für diese in erster Linie verwenden, und der Rest sind Ermessensentscheidungen. Wie könnten Sie den Zweck der Datei automatisch aktualisieren?

Generell bin ich aber nicht sehr angetan von solchen Dingen. Sie kennen bereits den Namen der Datei (duh), den Autor, den Bearbeiter, das Erstellungsdatum usw.: fragen Sie einfach Subversion. All dies an den Anfang der Datei zu stellen, verschwendet bestenfalls Platz und kann schlimmstenfalls falsch sein. Der Zweck der Datei ist in der Regel nützlich, aber Sie müssen sicher sein, dass sie auf dem neuesten Stand ist, was mehr eine Frage des Codierungsstils als alles andere ist.

0voto

dmw Punkte 1517

Meiner Meinung nach sind fast alle diese Felder völlig überflüssig und tragen in keiner Weise zum Beschreibungswert der Datei bei:

  1. Der Dateiname ist möglicherweise nur bei der Wiederherstellung nach einem Festplattencrash nützlich? Der Präprozessor fügt ihn automatisch ein, wenn er nützlich ist (z. B. wenn Sie versuchen, einen bösen Header-Fehler zu finden).

  2. Der Zweck einer .cpp Datei wird fast immer die Implementierung von einer oder mehreren .h Dateien, die eine oder mehrere Klassendeklarationen enthalten. Ein Kommentar, der den Zweck jeder Klasse beschreibt, ist besser in der Header-Datei unmittelbar vor der Klassendeklaration untergebracht, wo es auch wahrscheinlicher ist, dass er aktualisiert wird, wenn sich die Schnittstelle der Klasse ändert.

  3. Das Autorenfeld wird nie genau sein, sobald eine einzelne Zeilenänderung durch einen Dritten vorgenommen wird; verwenden Sie stattdessen die Befehle log / annotate / blame eines Revisionskontrollsystems, um dies zuverlässig zu verfolgen.

  4. "Geändert von", "Erstellt" und "RCS-ID" sind ähnlich nutzlos und veralten leicht. Eine RCS-ID kann nur die Version einer Datei bei der letzten Übergabe identifizieren, sie kann keine nicht versionierten Änderungen berücksichtigen, die seitdem vorgenommen wurden. Wenn Sie sich für die genaue Version einer Datei interessieren, sollten Sie stattdessen etwas Zuverlässiges wie eine MD5-Summe verwenden.

Bleibt noch der Hinweis auf das Urheberrecht und eine eventuelle Lizenzerklärung, die in einigen Rechtsordnungen angeblich erforderlich sind:

/* Copyright 2009, Your Company Name. All right reserved. */

Das Einfügen kann leicht mit einem Editor-Makro erreicht werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X