Jak nie popaść we frustrację, gdy chcesz mieć dokumentację
C# ma tę genialną zaletę, że pozwala komentować swoją treść specjalnymi znacznikami XML. Natychmiastowym efektem takich komentarzy jest ich prezentacja w postaci pomocy kontekstowej dla elementów kodu, które zostały nimi opatrzone. Drugie ich zastosowanie, to możliwość wygenerowania dla każdego pliku z treścią oprogramowania dokumentacji zawierającej elementy opatrzone wspomnianym typem komentarza. Powstają one w folderze, w którym umieszczane są binaria aplikacji.
Niestety – określanie tych plików mianem dokumentacji jest nadużyciem. Jest to jedynie plik XML zawierający nazwy elementów oprogramowania uzupełnione o treść wspomnianych komentarzy. Nie jest to w żaden sposób forma czytelna, którą da się przekazać komukolwiek, aby mógł z niej skorzystać. Oczywiście można zastosować odpowiednią transformatę XML, która pozwoli doprowadzić uzyskane dane XML do postaci czytelnej. Tylko, że tak naprawdę nadal będzie to tylko zestaw plików, owszem – bardziej czytelnych, ale nie stanowiących spójnej całości i niepowiązanych ze sobą. Nie będzie tu żadnego wstępu, jakiegoś drzewa pozwalającego docierać w sposób kontekstowy do informacji, mechanizmów wyszukiwania. W tym momencie czuje się zawód, że cała praca, która została włożona w opatrzenie kodu komentarzami XML, de facto nie jest całą pracą – nadal czeka sporo czynności i to – dla niektórych – niekoniecznie prostych (któż potrafi od ręki przygotować odpowiednią transformatę XML – trzeba szukać szczęścia – czyli gotowców – w sieci).
Na szczęście na stronie MSDN opisującej mechanizm dokumentacji XML można doczytać, że istnieje projekt Sandcastle, który pozwoli uzyskać pożądany rezultat, czyli dokumentację w jej ostatecznej, czytelnej postaci.
Tą drogą powędrowałem i pobrałem wspomniany projekt. Niestety wraz z nim pojawiły się kolejne trudności – aby uzyskać dokumentację konieczne było zapoznanie się z … inną dokumentacją – tą do pobranego narzędzia, albowiem pracuje ono wyłącznie w trybie poleceń, bez jakiegokolwiek, przyjaznego interfejsu okienkowego. Krótko mówiąc – oczekiwany cel zamiast się przybliżyć oddalił się jeszcze bardziej. Z początkowego zaznaczenia generuj dokumentację w Visual Studio, które miało po prostu dać oczekiwany rezultat, doszedłem do skomplikowanego systemu wymagającego znajomości kilkunastu parametrów. A ja pragnąłem po prostu czegoś, co uruchomione, umożliwi mi wskazanie folderu zawierającego projekt i wyciągnie z niego wszystkie znaczniki dokumentacji XML wraz z opisywanymi przez nie składnikami kodu, po czym przetworzy te dane do estetycznej i przejrzystej dokumentacji. Nie mogłem uwierzyć, że nie istnieje coś takiego (i to – oczywiście 😉 – za darmo).
Kontynuowałem więc poszukiwania. W ten sposób natrafiłem na współpracujący z Sandcastle (naprawdę, po moim z nim kontakcie twierdzę, że nazwa jest wyjątkowo trafiona) program DocProject for Sandcastle. Miałem nadzieję, że to narzędzie zrobi z zamku z piasku solidny zamek ze skały.
DocProject jest narzędziem, które integruje się z Visual Studio. Dostajemy wraz z nim – podobnie jak w mechanizmie testów jednostkowych Visual Studio – dodatkowy typ projektu z kilkoma szablonami. Ok – pomyślałem – nie jest to może dokładnie tak, jak oczekiwałem, ale dajmy temu szansę. Dodałem do istniejącego rozwiązania (Solution) projekt typu DocProject i zobaczyłem okno Kreatora. Jest dobrze – pomyślałem. Kreator zapytał mnie o silnik generowania dokumentacji (do wyboru był jedynie Sandcastle) – potwierdziłem, następnie poprosił o określenie sposobu prezentacji przez Sandcastle (bodajże zgodnie z zaleceniami wybrałem Visual Studio 2005), kolejno ustaliłem jeszcze format Compiled Help 1.x, a ekrany z ustawieniami opcjonalnymi zatwierdziłem w ich domyślnej postaci. Następnie zaznaczyłem oba dotychczasowe projekty w rozwiązaniu i zakończyłem pracę kreatora. VS zamrugało, zamigało, do drzewa projektu dodało się kilka folderów, po czym uzyskałem komunikat: „Adding a reference to a device project may produce unexpected results. Do you want to continue?”. Co to za pytanie pomyślałem? Oczywiście, że chcę – taki mam projekt i taki projekt muszę udokumentować. Kazałem zatem kontynuować.
I tyle było radości z DocProject.
Poszperałem jeszcze w dokumentacji nie chcąc tak łatwo zbaczać z drogi, którą wskazało mi MSDN. Szkoda jednak było czasu na mocowanie się z czymś, co po prostu powinno działać. Nie było innego wyjścia – włożyłem Google. Po uzyskaniu wyników – w większości pytań na forach – i zapoznaniu się z ich treścią, wyłoniło się dwóch kandydatów. Z tej dwójki wybrałem Doxygen – jego kontrkandydat miał jednak mniej możliwości (i był raczej martwy), a za Doxygenem przemawiały i długa historia istnienia, i jego aktualność oraz fakt, że obsługiwał wiele języków (co poszerzało krąg potencjalnych testerów, choć miałem też obawy czy nie zaważy to na generowaniu dokumentacji przez wspólny mianownik obsługiwanych języków).
Po zainstalowaniu i uruchomieniu moim oczom ukazał się następujący, niezbyt skomplikowany Kreator.
To było dokładnie to, czego oczekiwałem. Ustawiłem folder roboczy, nazwę projektu i jego opis, folder, gdzie znajdował się dokumentowany projekt i folder, gdzie ta dokumentacja miała trafić. Następnie użyłem Next, co zmieniło widok na następujący:
Tutaj jedynie wybrałem (z bardzo czytelnego zestawu ustawień) optymalizację dla Java oraz C# i ponownie użyłem Next, po czym ustawiłem konfigurację na tej stronie w poniższy sposób (dokumentacja miała mieć postać HTML):
Kolejne Next przeniosło mnie na pozycję Diagramów, którą pozostawiłem bez zmian. Można było na niej wybrać sposób generowania diagramów klas, ale nie były mi one potrzebne.
Następnie przeniosłem się na zakładkę Expert, na pozycję Project. Tutaj część ustawień pokrywała się z zakładką Wizard i – co jest bardzo wygodne – wszystkie odstępstwa od standardowych ustawień były wyróżnione czerwonym kolorem. Istotne było tutaj dla mnie jedynie ustawienie języka wyjściowego (OUTPUT_LANGUAGE – zaznaczone poniżej na czerwono), czego domyśliłem się dopiero po wygenerowaniu dokumentacji, kiedy okazało się, że jej statyczne elementy są w języku angielskim (dokumentacja miała być po polsku).
Kolejnym ustawieniem, które także zmieniłem dopiero po pierwszym wygenerowaniu dokumentacji, było włączenie do niej także metod statycznych (EXTRACT_STATIC – są one domyślnie przez Kreator pomijane).
To były właściwie wszystkie ustawienia, które okazały się potrzebne do wygenerowania dokumentacji w oczekiwanej przeze mnie postaci. Pozostało jedynie uruchomić generator, co realizowało się na zakładce Run, za pomocą przycisku Run doxygen.
Po przejrzeniu wygenerowanej dokumentacji zauważyłem, że przestrzenie nazw (które dokumentacja określa pakietami) nie posiadają opisów. Uzupełniłem je więc o stosowne znaczniki w kodzie oprogramowania (wystarczyło w jednym pliku, który przestrzeń nazw zawierał). Niestety powodowało to w Visual Studio problemy przy włączonej opcji generowania dokumentacji (komentarze XML są w tym miejscu dla VS niedopuszczalne), ale nie była ona już potrzebna, albowiem, jeśli używamy Doxygen, pobiera on opisy bezpośrednio z plików z kodem źródłowym, więc po wyłączeniu tej opcji, problem przestał być problemem.
Nie pasowało mi także to, że dokumentacja nie posiada żadnego wstępu. Ale i tutaj Doxygen stanął na wysokości zadania. Po krótkich poszukiwaniach okazało się, że wystarczy w głównym folderze projektu przygotować plik mainpage.md (np. w kodowaniu UTF-8), wypełnić go treścią, aby stał się on główną stroną dokumentacji. Co ciekawe, użycie w treści słów, które pokrywają się z nazwami klas powoduje automatycznie utworzenie skrótów do opisów tychże klas. Sam plik dopuszcza znaczniki o łatwej składni, zatem możliwe było uzyskanie zadowalającego formatowania takiej strony.
Końcowy efekt można zobaczyć poniżej:
Z pewnością będę używał Doxygen w kolejnych projektach, choć nie jest powiedziane, że wiecznie ;). Być może gdzieś tam w Internecie czeka na mnie jeszcze lepsze narzędzie ;).