ioninja

Под данным изречением-мемом, взятым с замечательной картинки Владимира Филонова, поставит свою подпись каждый человек, имеющий хотя бы отдалённое отношение к программированию. Весь вопрос, как? Как именно документировать-то?


Нижележащий текст преследует несколько целей:


  1. Дать краткий обзор (читай — немного погундеть на тему) неудовлетворительного состояния инструментария, применимого к хтоническим чудовищам мира C/C++;
  2. Предложить своё альтернативное решение (бесплатно-без-СМС-и-регистрации — проект некоммерческий и выложен на GitHub под MIT-лицензией);
  3. Призвать сообщество пообщаться на тему и собрать идеи;
  4. Пригласить присоединиться к разработке проекта на GitHub.

Сразу оговорюсь, что хотя проект создавался в первую очередь как альтернатива, а точнее, дополнение Doxygen для сишных и плюсовых API, архитектурно он в равной степени пригоден и для других языков. Это позволяет создавать порталы документации разноплановых библиотек — сами библиотеки могут быть написаны на разных языках, а в документации будет единство стиля во внешнем виде и поведении.




Мотивация


По большому счёту, подходов к документированию API и библиотек — плюсовых или нет — ровно два.


  • Первый, это писать всё ручками.

Даже неважно в чём — в Help & Manual, RoboHelp, Word или другом редакторе. Несмотря на то, что этот традиционный способ всем понятен и по-прежнему широко используется, я глубоко убеждён что он в корне неверен. Дело в том, что он порождает документацию, которая всё время местами нерелевантна и отстаёт от объекта документации. Поддержка согласованности между созданными раздельно, а зачастую ещё и разными людьми, документацией и постоянно эволюционирующим API библиотеки — не эволюционируют только умершие или замороженные продукты! — это колоссальная задача, лишь немногим более лёгкая написания первичной документации.


  • Второй, "правильный" подход, состоит в том, чтобы генерировать документацию по исходникам автоматически.

Специально обученный парсер пробегает по исходникам, вычленяет особым образом оформленные комментарии с документацией и строит структуру дерева публичных объявлений API. После этого генерируется документация в нужном формате — меня, как, полагаю, и большинство, в первую очередь интересует HTML и PDF. Основным преимуществом данного подхода является гарантированная когерентность объявлений в исходниках API и в конечной документации. Даже при полном отсутствии в исходниках содержательных комментариев с собственно "документацией", в конце мы будем иметь прекрасный снимок состояния API библиотеки, с возможностью "попрыгать" по объявлениям и описаниям типов, и т.д.


Итак, с вашего позволения, я сконцентрируюсь на "правильном" подходе с автогенерацией. Какие варианты у нас имеются тут? Увы, для документации C/C++ на данный момент имеется и реально используется печально мало: Doxygen да QDoc. И с этими двумя тоже далеко не всё гладко.


Doxygen — первый по-настоящему успешный проект по вытаскиванию комментариев из кода на плюсах и превращению оных в HTML-документацию с гиперссылками, картинками графов наследования, вызовов и т.д. В отличие от своего прямого родителя — первопроходца Doc++, так никогда и не получившего достаточного распространения, Doxygen сейчас — это де-факто стандарт документирования кода на C/C++. И всё это было бы замечательно, если бы не два "но":


  • Стандартный генерируемый доксигеном HTML, как бы это помягче сказать… не обременён элегантностью.

Конечно, тут есть место субъективизму. Я вполне допускаю, что в мире существуют не столь придирчивые люди, которых доксигеновский выхлоп полностью устраивает (рискну предположить, однако, что профессиональных дизайнеров среди них не окажется). Но даже если умолчальный доксигеновский HTML и устраивает кого-то с визуальной точки зрения (а серьёзно, есть такие, кому он и вправду нравится эстетически? напишите в комментариях!), очень часто хочется поменять и настроить что-то выходящее за рамки подкручивания CSS — например, упечь объявления в <pre> и расставить отступы и пробелы в соответствии с принятым в данной конкретной библиотеке coding-style. Это подводит нас ко второй, более фундаментальной проблеме Doxygen:


  • Doxygen за свою долгую жизнь так и не отрастил настоящую, модульную настраиваемость.

Да, есть Doxyfile с кучей переменных, есть возможность менять HTML шапки и CSS, но архитектурно — всё захардкожено в монолитное C++ ядро! Причём захардкожен как front-end, а именно, парсеры исходников, так и back-end — генераторы HTML, PDF, RTF и другого (среди которого, слава небесам, есть и XML).


QDoc по умолчанию выдаёт гораздо, гораздо более симпатичный HTML, чем Doxygen. К сожалению, если требуется что-то не по умолчанию, то QDoc страдает всё той же врождённой деревянностью, что и Doxygen (растущей, понятно, из той же самой ж... захардкоженности и парсера, и генератора в монолитное плюсовое ядро). В дополнение к своей деревянности, QDoc, в отличие от Doxygen, имеет всего лишь один входной парсер — для QT-диалекта C++ (со всеми Q_OBJECT, Q_PROPERTY, foreach, и т.д. жёстко трактуемыми как ключевые слова). И при этом, — что уж совсем ни в какие ворота, — не умеет генерировать PDF!


Альтернатива


Предлагается заменить один инструмент конвейером. Вместо


Doxygen -> (HTML, PDF, ...)

… будем использовать следующий pipeline:


Doxygen -> (XML) ->
    -> Некий-Мост -> (reStructuredText) ->
        -> Sphinx -> (HTML, PDF, ...)

Что оставляем старого?


Разработчики знают как и уже привыкли документировать C/C++ код с помощью Doxygen-комментариев:


/*!
    \brief This is a brief documentation for class Foo.

    This is a detailed documentation for class Foo.
    ...
 */
class Foo
{
    // ...
}

Зачем изобретать новый синтаксис? Будем писать документацию так же, как и раньше!


Doxygen умеет вытаскивать документацию из исходников и класть её вместе с деревом объявлений в XML базу данных. Прекрасно! Это будет нашим front-end.


Ещё легче ответить на вопрос о том, что использовать в качестве back-end — конечно, Sphinx. Sphinx заслуженно получил колоссальное распространение как инструмент написания технической документации. Он выдаёт весьма вкусно выглядящий HTML с поддержкой полноценных тем (а не просто CSS!), умеет склеивать всё в одну HTML-простыню, генерировать документацию в PDF, EPUB и множестве других форматов — и всё это из коробки! Но что самое главное, он полностью настраиваем с помощью Python-скриптов, причём их можно применять как для тюнинга внешнего вида, так и для расширения входного языка (каковым для Sphinx является reStructuredText) — а именно, дописывать свои директивы и потом использовать их в документации.


Осталось подружить Doxygen и Sphinx.


Строим мост


Замечу, что я не первый, кто пытался построить мост между Doxygen и Sphinx. Относительную известность приобрёл проект breathe, написанный на Python как расширение для Sphinx. В настоящий момент проект не слишком активно ковыряется отвёрточкой, и, увы, из коробки не пригоден для серьёзных задач. Архитектурно он устроен следующим образом: он парсит XML-выхлоп доксигена и создаёт узлы reStructuredText дерева в памяти напрямую.


Я же решил пойти несколько другим путём. Doxyrest — так называется наш мост — парсит доксигеновские .xml файлы, а затем отдаёт распарсенный XML и набор файлов-шаблонов в шаблонизатор (string template engine, template processor). Шаблонизатор генерирует файлы с reStructuredText, и уже эти .rst файлы передаются в Sphinx-back-end для получения окончательной документации в заданном формате.


Основная фишка — конечно же, использование шаблонизатора. Это позволяет полностью настраивать структуру документации: менять порядок и группировать документируемые объекты (классы/функции/свойства и т.д.), настраивать стиль объявлений (где и как использовать отступы, пробелы, переносы строк и т.д.), использовать логику произвольной сложности для включения или не включения данного конкретного объекта в документацию, и так далее — и всё это без перекомпиляции, просто правкой входных шаблонов!


Но главное — подход с шаблонизатором позволяет применять Doxyrest для абсолютного большинства любых других языков, и в частности, разнообразных DSL — для которых никто и никогда не будет делать специализированных систем документации. Doxygen не умеет парсить ваш язык? Взяли компилятор языка, добавили туда генерацию Doxygen-подобного XML по уже имеющемуся AST, затем исправили шаблоны выходных .rst файлов — чтобы объявления в документации были с нужным синтаксисом, — и всё! Ваш язык теперь можно документировать с помощью Doxygen-комментариев и получать на выходе красивую Sphinx-документацию.


В настоящий момент для шаблонизации используется язык Lua (просто потому что у меня уже была готовая и отлаженная библиотечка Lua string templates), но в теории ничто не мешает добавить поддержку и других языков шаблонизации.


Выглядят и работают шаблоны как-то так:


    Title
    =====

    %{
    if false then
    }
    This text will be excluded..
    %{
    end -- if

    for i = 1, 3 do
    }
    * List item $i
    %{
    end -- for
    }

На выходе будем иметь:


    Title
    =====

    * List item 1
    * List item 2
    * List item 3

Примеры использования


Лучше один раз увидеть, чем сто раз услышать. Посему, вместо заключения я решил просто привести ссылки на результат работы Doxyrest в применении к различным языкам:



Несмотря на незаконченность содержательной части документации по ссылкам выше (собственно описания классов, функций и т.д.), всего этого должно быть достаточно для демонстрации работоспособности метода.


Страничка проекта на GitHub: http://github.com/vovkos/doxyrest


Проект выложен под одной из самых нестрогих лицензий в мире — The MIT License. Смотрите, пробуйте, присоединяйтесь к разработке. А я с удовольствием отвечу на все вопросы в комментариях.

Поделиться с друзьями
-->

Комментарии (42)


  1. saluev
    27.12.2016 15:45
    +11

    Эта вот манера постоянно вставлять жирный шрифт довольно-таки сильно затрудняет чтение этого текста.


    1. vovkos
      27.12.2016 18:27

      Встречал и прямо противополжное мнение — что использование смысловых акцентов здорово помогает при чтении при диагонали. Я раньше вот тоже не любил жирные акценты, а сейчас склоняюсь к тому, что и вправду помогает. Одно очевидно — всем не угодишь.


      1. Zolushok
        27.12.2016 18:58

        Помогает, конечно. Перебор в данном случае только с концентрацией этих смысловых акцентов.
        Но это всё по большому счёту мелочи. Глаза не лопнули, вот и славно.


      1. saluev
        27.12.2016 19:13
        +1

        Во-первых, как Zolushok отметил, в этой статье это ни разу не ускоряет (потому что жирного много в каждом абзаце), а во-вторых, кажется, что акцент должен быть менее заметен, чтобы не мешать читать текст. (У меня лично на каждом жирном слове в голове происходит пафосная пауза и преподавательским тоном диктовка — отвлекает!)


        1. vovkos
          27.12.2016 19:57

          Болд или италик это, наверно, всё-таки личные предпочтения. А замечание по количеству акцентов принято.


          1. Zolushok
            28.12.2016 13:19
            +1

            Ну и опять же, любые дополнительные выделения в тексте (за исключением строго оговоренных, когда читатель заранее знает, что значит каждый болд или италик), будь то смайлики или разноцветье шрифтов — это компенсация недостаточного владения классическими выразительными средствами письменной речи.

            Как и улыбки-скобочки, они несомненно имеют право на жизнь, но как-то так…

            Вопрос по сути статьи — скажите, а doxygen вроде бы умеет выдавать выхлоп в docbook-формате. а уж для него всяких генераторов в разных форматов написано немало. Такой вариант чем-то не устроил? Я просто сам давно не крутил всю эту кухню в руках, ибо java/javadoc сейчас наше всё


            1. vovkos
              29.12.2016 01:34
              -1

              Ну и опять же, любые дополнительные выделения в тексте (за исключением строго оговоренных, когда читатель заранее знает, что значит каждый болд или италик), будь то смайлики или разноцветье шрифтов — это компенсация недостаточного владения классическими выразительными средствами письменной речи.

              А мне кажется, визуальные акценты помогают-таки при просматривании статей по диагонали. Вопрос количества и баланса, конечно, открытый (и во многом субъективный). Но вообще я за акценты. Как говорится, let's agree to disagree :)


              Вопрос по сути статьи — скажите, а doxygen вроде бы умеет выдавать выхлоп в docbook-формате. а уж для него всяких генераторов в разных форматов написано немало. Такой вариант чем-то не устроил?

              Если честно, то не пробовал генерировать HTML из доксигеновского DocBook выхода. Навскидку не вижу причин, почему это может давать намного лучший результат, чем просто подкрутка CSS и шапок у доксигеновского HTML. Впрочем, если у вас пример красивой документации, полученной таким методом — кидайте, можно будет обсудить более предметно.


    1. riky
      28.12.2016 14:51

      зачем себя мучать? добавьте просто стили в консоль браузера

      .content strong {
      font-weight: normal;
      }

      либо еще проще — закладку в браузер
      javascript:$('.content strong').css('font-weight','normal')


  1. estin
    27.12.2016 16:58
    +1

    Зачем изобретать новый синтаксис? Будем писать документацию так же, как и раньше!

    Затем что если хочется документацию иметь красивую, со сложной связностью и легко расширяемую, то лучше сразу писать доки на Sphinx. А так получается что вы хотите лоск Sphinx и сразу же загоняете себя в рамки Doxygen.


    Для себя выбрал другой путь — все документирование на Sphinx для любых исходников, а сбор документации через плагин Sphinx, который построен на механизме autodoc. Вот мой sphinxcontrib-autoanysrc и есть еще куча аналогов.


    Плюсы:


    • любые исходники документируй хоть lua, хоть SQL и встраивай UML диаграммы, блок схемы и любые другие навороты Sphinx

    Минусы:


    • сигнатуру приходится дублировать руками, но можно и расширить плагин парсер, что не так уже тривиально )


    1. vovkos
      27.12.2016 18:31
      +1

      Никаких рамок, только лоск =)

      Вы вольны использовать любые конструкции Sphinx внутри комментариев, а от Доксигена брать только синтаксис привязки комментария с документацией к конкретному объекту исходников.

      Типа:

      /*!
      	Detailed documentation for ``foo`` with some **reStructuredText** markup.
      
      	Usage:
      
      	.. code:: cpp
      
      		foo ("bar"); // <-- OK
      		foo (NULL);  // error, name can't be NULL
      
      	In master conf.py you can add your own Sphinx extensions and then invoke custom directives:
      
      	.. my-custom-directive::
      
      		my-custom-directive-content
       */
      
       void foo (const char* name);
      
      

      А вообще по-моему мы сходимся в оценке Sphinx как удачного средства генерации финального варианта документации. Что предлагается в данном продукте — так это автоматическая генерация объявлений и автоматическая же привязка к ним смыслового наполнения документации.


  1. eyeofhell
    27.12.2016 18:34
    +1

    Если мне не изменяет память, картинка — совместное творчество Владимира и его супруги. Раздавалась ограниченным тиражом в этом году на одном из Moscow Python митапов в Москве. У меня в офисе висит :)


    1. vovkos
      27.12.2016 19:41

      Спасибо, поправил


  1. demp
    27.12.2016 19:10

    Есть еще standardese, попытка создать новую версию генератора документации для C++ проектов. Его автор использует libclang для парсинга С++ кода и добавляет новые директивы в комментарии.


    1. vovkos
      27.12.2016 20:07

      Если они не используют шаблонизатор (а судя по составу репозитория, там есть только CPP и Bash), то наступают на те же самые грабли, что и Doxygen — нельзя хардкодить генерацию HTML.

      То есть всё, что они получат в итоге — это Doxygen с Clang в качестве парсера, но с таким же деревянным выходом. Кстати, если не ошибаюсь, автор Doxygen уже начал прикручивать Clang и сам.


      1. demp
        28.12.2016 00:20

        If you pass a file that is not a source file, it will be treated as template file and processed. This allows advanced control over the output or writing additional documentation files.

        Так что используя простейший язык шаблонов можно в какой-то мере влиять на генерируемый результат. Выходные форматы как и у Doxygen — markdown, html, xml, man, latex.


        1. vovkos
          28.12.2016 09:20

          Посмотрел описание языка шаблонизации — ой, зря они свой язык стали писать, ой зря...


          Им бы взять Lua или Python — и то, и другое легко встраивается в плюсовые приложения. Сейчас вся эта кухня с новым языком даёт слишком уж ограниченные возможности по настройке вывода — на неизвестном и неотлаженном языке, без стандартной библиотеки, да ещё и с вырвиглазным синтаксисом (standardese_for, standardese_else_if и т.д.).


          Потом, сама идея с опциональностью шаблонов наводит на мысль, что шаблоны эти планируется использовать лишь как дополнение к автосгенерированному дереву объявлений, на внешний вид которого можно повлиять только настроечными переменными — как и в Doxygen.


          Вполне возможно, я что-то упсутил, но у них, увы, нет примеров использования этих шаблонов — в репозитории только плюсы, bash и cmake..


  1. LLWE_FUL
    27.12.2016 19:42
    -2

    > писать всё ручками.
    > я глубоко убеждён что [этот способ] в корне неверен. Дело в том, что он порождает документацию, которая всё время [...] отстаёт от объекта документации.

    Дело в том, что если сначала пишется API как получится, а потом пост-фактум под него пишется документация, то качество этого API будет стремиться к нулю или даже дальше в минус бесконечность. При правильном подходе, документация пишется на этапе проектирования и всегда опережает код. А код и тесты пишутся уже в соответствии с документацией. При таком подходе, и код будет чище, и если имплементация в результате будет отличаться от документации, тесты это покажут.

    > «правильный» подход, состоит в том, чтобы генерировать документацию по исходникам автоматически.
    > Специально обученный парсер пробегает по исходникам, вычленяет особым образом оформленные комментарии с документацией.

    Какая разница, хранится документация в отдельном файле или в комментариях в файле с исходниками, если она все равно пишется пост-фактум, и никто не заметит, если какие-то ее части не будут соответствовать реализации? Если этап проектирования пропустили и правят код по наитию, скорее всего, интерфейсы будут меняться много раз по ходу работы, и кое-где забудут обновить комментарий с описанием.

    Дальше не читал.


    1. vovkos
      27.12.2016 19:52
      +5

      Дело в том, что если сначала пишется API как получится, а потом пост-фактум под него пишется документация, то качество этого API будет стремиться к нулю или даже дальше в минус бесконечность. При правильном подходе, документация пишется на этапе проектирования и всегда опережает код. А код и тесты пишутся уже в соответствии с документацией. При таком подходе, и код будет чище, и если имплементация в результате будет отличаться от документации, тесты это покажут.


      Это работает только для сферических проектов в вакууме. На практике же набросанные на этапе проектирования интерфейсы безжалостно корёжатся при столкновениях с действительностью. Добавляются и убираются аргументы, методы и целые классы. Именно поэтому документация должна генерироваться по исходникам, а не быть написана отдельно (заранее или нет).

      Какая разница, хранится документация в отдельном файле или в комментариях в файле с исходниками, если она все равно пишется пост-фактум, и никто не заметит, если какие-то ее части не будут соответствовать реализации? Если этап проектирования пропустили и правят код по наитию, скорее всего, интерфейсы будут меняться много раз по ходу работы, и кое-где забудут обновить комментарий с описанием.


      Разница очень большая. Безусловно вы правы в том, что при любом подходе смысловой контент документации может отстать от эволюционирующего API. Но вот дерево объявлений в случае с авто-генерацией всегда будет релеванто — в отличие от отдельной документации. Глядя в авто-сгенерированную документацию вы всегда видите, какие аргументы принимает метод и что он возвращает. И всегда можно покликать и попутешествовать по типам, посмотреть, гда есть какие поля, методы, свойства и т.д.

      Дальше не читал.


      Ваше право.


      1. LLWE_FUL
        27.12.2016 19:57
        -3

        > Это работает только для сферических проектов в вакууме.
        Я тоже так думал в первые несколько лет своей карьеры. Потом понял, что как раз наоборот: без этого нормально не работает ни один проект, для которого вообще имеет смысл писать документацию.


        1. khim
          29.12.2016 04:07
          +1

          То есть вот прямо так? Ни Гугл, ни Яндекс не работают? Андроиды всякие, Браузеры и тому подобное — тоже плод воображения?

          Ню-ню, далеко вы пойдёте с таким подходом.

          Да, есть области, где описанные вами подходы работают. В основном с заказным софтом, где если что-то забыли при проектировании — то всё, мыши будут теперь этот кактус есть лет десять, пока их кровавые слёзы кого-нибудь не разжалобят.

          Но заказным ПО мир не ограничивается…


    1. Ndochp
      27.12.2016 20:26
      +1

      Документация это не ТЗ.
      Нужно написать ТЗ, потом код, потом документацию.
      И хуже того, поддерживать документацию актуальной. При этом новые ТЗ должны быть не подправленными старыми, а описанием новых требований. А документация — подправленной старой. Поэтому иного пути, чем генерить ее по коду — нету. (ну, руками еще можно. Теоретически.)


      1. LLWE_FUL
        27.12.2016 20:42
        -2

        > Документация это не ТЗ.
        А где я говорил иначе?

        Порядок действий очень простой: Product spec (чего хочет заказчик) -> Tech Spec (как это реализовать технически в рамках текущей кодовой базы, как меняются архитектура, базы данных, API; как писать все не-тривиальные новые части) -> обновление технической документации -> согласование изменений (до того, как потратили кучу времени на написание кода) -> код -> тестирование на соответствие имплементации и документации.

        Если начать писать код до того, как полностью разобрались с задачей или договорились со всеми заинтересованными сторонами, поимеешь кучу косяков и потратишь намного больше времени.


        1. vovkos
          28.12.2016 09:20
          +4

          Вся цепочка рассуждений исходит из неверных предположений, что заказчик знает, чего хочет, а с задачей можно полностью разобраться до начала работ.


          1. LLWE_FUL
            28.12.2016 15:18
            -3

            Я исхожу из предположения, что с задачей придется разобраться до окончания работ, и если уж от этого не убежать, то будет на порядок (а иногда и на два) дешевле сначала разобраться с задачей, а потом писать код, а не писать и переписывать код, пока не станет понятно, что же он в конце концов должен делать.

            Но судя по комментариям, мое предположение о том, что задачу на каком-то этапе все равно нужно будет понять, является ошибочным.


            1. khim
              29.12.2016 04:12
              +2

              Вы находите из предположения что у работ есть начало, окончание и заказчик. А для огромного количества ПО нет ни того, ни другого, ни третьего, нет и в помине.

              Рассмотрите какой-нибудь простой пример: Chrome. Где у вас там будет начало, окончание и кто будет заказчиком?


        1. Ndochp
          28.12.2016 14:55

          Описание и код в равной мере продукт для потребления заказчиком, (в отличия от спеков, которые продукт потребления подрядчика). Соответственно, после тех спеки можно писать и то, и другое. Но удобнее сначала код.
          А поиметь проблемы можно и согласовав документацию и получив претензии к функциональности, так как «а по описанию мы подумали, что оно иначе выглядеть будет».


          1. LLWE_FUL
            28.12.2016 15:09
            -4

            > «а по описанию мы подумали, что оно иначе выглядеть будет».
            Именно поэтому первым в цепочке стоит product design, который включает в себя описание функциональности и скетчи интерфейсов для пользователя. Пока эти аспекты не согласованы с заказчиком, нет смысла начинать писать код.

            Я, наверное, неправильно понял о чем речь в статье. Тут, похоже, собрались разработчики именно «хтонических чудовищ», наподобие одноразовых сайтов-визиток для заказчиков, которые сами не знают, чего хотят и не в состоянии оценить, чего же им в конце концов наваяли. В этой области, конечно, и подходы другие, и опыта построения сложных систем, которые должны by design работать и развиваться в течение многих лет, набраться негде.
            Только тогда я не понимаю, откуда в этих сайтах-визитках берутся API, для которых может понадобиться документация, но я много чего не понимаю в вашей кухне.


            1. Ndochp
              28.12.2016 15:21
              +2

              Ну, сейчас, кажется если штука не интегрируется — то она не нужна. А если интегрируется — то нужен API.
              А сложные системы что, прям реально по водопаду живут? и вот прям если через полгода проекта требования поменялись к цвету кнопок, то как в документации согласовали, так и кодим. А как закодим, будем изменения согласовывать.
              Или останавливаем разработку на время согласования обновленной документации?

              И скетчи — они статика и абстрация. А вот подробностей они могут и не нести. А подробности могут повлечь еще один параметр/значение перечисления в функцию описанного API. Жирность шрифта, например.


              1. LLWE_FUL
                28.12.2016 15:33
                -3

                > А сложные системы что, прям реально по водопаду живут?

                Более-менее. По крайней мере подход «за две недели добавим вот эту фичу, а как добавлять следующую, будем думать потом» работает очень плохо. Приходится много думать и планировать наперед, иногда на год-два вперед. Иначе код за год настолько зарастает костылями, что второй год целиком уходит на разгребание бардака, а не на развитие функционала. Примеров больших проектов, которые через пару лет разработки начали переписывать все с нуля — масса, и часто причина именно в этом: разгрести старый говнокод оказалось дороже, чем написать заново с нормальным планированием.

                > если требования поменялись к цвету кнопок, то как в документации согласовали, так и кодим.

                Зависит от масштабов изменения. Часто — да, реализуют по предыдущей версии документации, а новую функциональность вносят только в одной из следующих итераций, после согласования новой документации.

                > останавливаем разработку на время согласования обновленной документации?

                Тоже случается. Если изменение значительное и много чего ломает, то оказывается дешевле заморозить разработку этой фичи или даже всего проекта, пока не будет ясности с требованиями. Продолжать писать код, когда не понятно, что же он должен делать в конце — лишняя трата времени.
                Лучше в это время занять программистов всякими низкоприоритетными задачами, которые было бы неплохо сделать, но вечно не хватает времени. В больших проектах таких задач всегда вагон и маленькая тележка.


      1. Serj_By
        28.12.2016 17:01
        +1

        Руками править отдельно написанную документацию — это просто бессмысленная трата времени. Открыл проект, подправил код. Лезть еще и документацию править? Не проще ли перейти на некое количество строк вверх, подправить doxygen/javadoc документацию и продолжить работать?


    1. Serj_By
      28.12.2016 17:16
      +2

      Дело в том, что если сначала пишется API как получится, а потом пост-фактум под него пишется документация, то качество этого API будет стремиться к нулю или даже дальше в минус бесконечность.

      Дальше не читал (с).

      Как предполагается сразу написать сразу документацию, а потом под нее подгонять код? Нет, ну это понятно в случае с библиотеками, подключаемыми ресурсами. Но на живом проекте такое попросту нереально. Допустим даже, с использованием такого подхода сделали продукт. Состоялся релиз. Получили фидбек от пользователей. Посидели, поговорили, подумали что добавить, что убрать, что поменять. Окей, составили тех-спецификацию. Насколько Вы уверены в том, что она просто вот возьмет и идеально с учетом всех хотелок ляжет на архитектуру? Я обычно уверен процента на 2-3 и редко ошибаюсь. Как правило, это пустая трата времени, по крайней мере на больших продуктах. Мелочевка одноразовая — тут не вопрос. Но там как правило и документация не сильно нужна. А в серьезных проектах, которые из многих модулей состоят — вот так просто взять и составить документацию по всем API и тех. задание по ней — это анрил. Нужна еще целая куча согласований по ходу разработки. Кому-то нужны данные в таком виде, кому-то в таком. На берегу в больших проектах редко получается договориться.


      1. LLWE_FUL
        28.12.2016 18:24
        -2

        Мой опыт говорит как раз об обратном: если сразу задуматься, что нужно сделать, кому какие данные и в каком формате нужны, как изменения затрагивают разные части проекта, — то можно написать детальную документацию на всё, согласовать изменение со всеми заинтересованными сторонами, а потом отдать написание кода джунам, потому что эта задача становится тривиальной.
        И наоборот — если сразу влезть в код и начать что-то менять без того, чтобы предварительно подумать, то получится игра в перетягивание одеяла: что-то поменяли, что-то от этого сломалось, его починили, но сломалось что-то другое, неделю рефакторили какой-то модуль, но потом оказалось, что он теперь не состыкуется с каким-то другим, и нужно откатывать все изменения… В результате вся та же работа по согласованию все равно будет делаться, только в процессе тратится куча лишнего времени на написание и переписывание кода, а что-то, что сломалось, может остаться незамеченным.
        Сроки при этом растягиваются на порядок (и их становится невозможно нормально оценить заранее, что приводит к срывам и кранчам со всеми вытекающими), а качество всей системы заметно страдает (что еще больше усугубляет ситуацию). И чем больше проект, тем сильнее все это проявляется.

        > а потом под нее подгонять код?
        Писать код по спецификации, да. Намного проще и на порядок-два быстрее, чем по-ковбойски бросаться в написание кода без предварительного включения головы.

        > вот так просто взять и составить документацию по всем API и тех. задание по ней — это анрил
        Как раз наоборот, написать весь код так, чтобы все работало и не было костылей на каждом шагу без предварительного планирования — анрил.

        Но я уже выше писал, что, похоже, неправильно оценил вид проектов, с которыми местная публика в основном работает, а в вашей кухне я не разбираюсь. Возможно, в вашем случае мой опыт и неприменим.


  1. mikeus
    28.12.2016 00:15

    Но даже если умолчальный доксигеновский HTML и устраивает кого-то с визуальной точки зрения (а серьёзно, есть такие, кому он и вправду нравится эстетически? напишите в комментариях!), очень часто хочется поменять и настроить что-то выходящее за рамки подкручивания CSS — например, упечь объявления в <pre> и расставить отступы и пробелы в соответствии с принятым в данной конкретной библиотеке coding-style.
    Дефолтный вывод докигена ужастен (от слов «ужас» и «жесть»). Настолько что когда я первый раз увидел что он сгенерил, то сразу пошел искать возможные альтернативные инструменты. Но не найдя ничего более функционального с точки зрения именно процесса создания и поддержания актуальной документации из исходных файлов (равно как из любых других дополнительных источников документирования проекта), пришлось обратиться к правке HTML_STYLESHEET чтобы привести вывод в более менее приличный вид, и LAYOUT_FILE для того чтобы подкорректировать структуру документации сделав её более понятной, чтобы некоторые дефолтно генерируемые разделы не вводили пользователя в состояние фрустрации.

    Пример: линк. Собственно сам веб-сайт doxygen сгенерирован doxygen.

    Это подводит нас ко второй, более фундаментальной проблеме Doxygen...
    Проблем у доксигена полно, да. Но по функциональности и возможностям настройки обработки исходников C/C++ для генерации документации он пока не имеет равных. Он может быть и «деревянный» у себя внутри, но в конце концов после изучения и настройки работает и делает то что нужно: генерирует актуальную полноценную документацию из исходников и прочих файлов описания с минимальными трудозатратами на поддержку собственно документирования в исходниках рядом с актуальным кодом.


    1. vovkos
      28.12.2016 09:22
      +1

      Совершенно верно — как средство разбора и вытаскивания документирующих комментариев он пока не имеет равных. Кроме того, когда допилится интеграция с Clang (а то сейчас она какая-то уж слишком экспериментальная), этих самых равных и искать никакого смысла не будет.


      А сделать красивый вывод по информации, полученной Доксигеном — в этом и есть вся соль предлагаемого мной проекта. Доксиген умеет доставать информацию из исходников. Sphinx умеет генерировать красивый — и, что главное, настраиваемый, — HTML. Doxyrest — мост между этими двумя товарищами.


  1. dendron
    28.12.2016 00:26

    В чём разница между поддержанием документации в отдельном файле или в коде?

    По личному опыту документация Doxygen совершенно бестолкова. Гораздо полезнее абстрактная документация описывающая общую идею и щедро расставленные обычные текстовые комментарии, чем бессмысленные аннотации аргументов, для нормального чтения которых код ещё надо прогнать через утилиту в отдельный файл. Не говоря уж о том, что менять такой код — тоже удовольствия мало.

    Хотя подозреваю всё это может неплохо работать в случае закрытых проприетарных библиотек, которые поставляются клиентам.


    1. mikeus
      28.12.2016 01:00

      Так что мешает подключить файлы с абстрактным описанием в документацию doxygen, а обычные комментарии в коде с минимальными усилиями превратить в doxy-комментарии? Бессмысленные аннотации объявлений генерируются doxygen автоматом и это может быть отключено, тогда doxygen выведет только то, что было реально задокументировано.


      1. vovkos
        28.12.2016 09:28
        +1

        Всё правильно. А в случае с использованием Doxyrest, отдельные страницы с абстрактным описанием — это будут просто .rst файлы, скармливаемые Sphinx напрямую.


        1. mikeus
          28.12.2016 13:33

          И сейчас в случае с doxygen это просто файлы Markdown скармливаемые doxygen напрямую. И это в результате может стать не просто отдельной самостоятельной страницей в документации, но в них можно указать какие отрывки текста должны появиться в какой странице или в какой раздел («модуль» в терминах doxygen) добавиться к автоматически сгенерированной документации кода. (К сожалению вот только локализовать место вывода до конкретной функции-члена класса нельзя.)


          1. vovkos
            29.12.2016 01:37

            Ну я собственно и не противопоставлял — просто сказал, что и с Doxyrest тоже можно создавать самостоятельные страницы с документацией как обычные .rst файлы. И конечно, и с Doxygen, и с Doxyrest из этих самостоятельных страниц можно ссылаться на авто-сгенерированные страницы API.


            Другое дело что Doxyrest перекладывает всю работу по созданию финальной красивой HTML страницы на инструмент, который прекрасно с этим справляется (значительно лучше, чем Doxygen). Вот и всё.


    1. vovkos
      28.12.2016 09:27
      +1

      В чём разница между поддержанием документации в отдельном файле или в коде?

      Я уже писал выше — при авто-генерации документации имеется гарантия релевантности всех объявлений. Вы можете побегать по API, посмотреть какие аргументы принимаются, что возвращается, какие есть поля и т.д.


      По личному опыту документация Doxygen совершенно бестолкова.

      Бестолковость абсолютного большинства примеров Доксигеновской документации, действительно имеет место быть. Но это проблема конкретного контента, а не подхода, согласитесь? Можно ведь взять и написать толковую документацию, а не просто: open открывает, get возвращает. Но у меня есть смелая теория, почему сейчас всё обстоит именно так.


      Разработчики не хотят тратить усилия на написание толковых комментариев, потому что — барабанная дробь — конечная Доксигеновская документация всё равно будет выглядеть как говно!


      Исправить это — и есть главная цель проекта Doxyrest.


      1. lexkazakov
        28.12.2016 10:57
        +2

        Разработчики не хотят тратить усилия на написание толковых комментариев, потому что — барабанная дробь — конечная Доксигеновская документация всё равно будет выглядеть как говно!

        Я вам больше скажу: разработчики в принципе не любят документацию писать.


        1. vovkos
          28.12.2016 11:22
          +1

          Что правда то правда. Тогда я переформулирую:


          Даже в тех (редких) случаях, когда разработчики и рады были бы написать нечто толковое в документации, их останавливает то, что… и дальше по тексту ;)