:date: 2016-07-10

=====================
Sunday, July 10, 2016
=====================

About software documentation
============================

Thiago Nascimento, in his article `Software without documentation -
Legend or Reality?
<https://www.linkedin.com/pulse/software-without-documentation-legend-reality-thiago-nascimento>`_
deplores that free software often lacks good documentation.

Thiago, I agree with you about the lack itself.  Yes, there are many
programmers who write great software and who lose motivation or even
fail when they are asked to write also the documention about their
work.  But this is not *deplorable*, it is *normal*. Writing software
and writing *about* software are two very different things, and most
people are more or less focussed in one of them.

No, I don't think that team leaders and project managers usually
underestimate the importance of documentation for the maintenance and
the life cycle of a software project.

The deplorable thing --if you want something to deplore-- might be
that team leaders and project managers don't always have a spirit of
sharing.  But even this is actually normal as long as most of us
believe that software can be seen as private property
(`Why software must be free <http://hw.saffre-rumma.net/fs/index.html>`_).

I liked your classification of "documentation types", it inspired me
to write my own (which is very similar):

- Functional documentation describes the features of the software
  using a language that is comprehensible by project stakeholders and
  developers.

- Technical documentation describes the technical aspects of the
  software in a language used mainly by the developers themselves.

- User documentation describes the handling of the software by the
  user.

- Historic documentation describes the evolution of the software and
  the lessons learned throughout its construction.


Loading demo fixtures
=====================

Ticket :ticket:`1029` caused quite some email traffic between
Grigorij, Hamza and me.  It took us some time to understand that the
error occurs when the current directory contains an
:file:`__init__.py` file and a file :file:`demo.py`. You can reproduce
it manually like this::

    $ cd lino_book/projects/min1/settings
    $ python ../manage.py initdb_demo

Unlike one of my theories at some moment, the error works
independently of the :setting:`LINO_CACHE_ROOT` setting.

Note that there are different ways of running the
:manage:`initdb_demo` command:

1. cd to the project directory and and run `python manage.py
   initdb_demo`::

      $ cd ~/repositories/book/lino_book/projects/max
      $ python manage.py initdb_demo

2. do *not* cd into any directory, but specify the settings module::

      $ django-admin.py initdb_demo --settings=lino_book.projects.min9.settings

3. cd to the root of a repository and run the :cmd:`inv prep`
   command (which runs :manage:`initdb_demo` for all demo projects::

      $ cd ~/repositories/book
      $ inv prep

The error was so difficult to reproduce because it does not occur in
cases 1 and 2, and even in case 3 only when :setting:`LINO_CACHE_ROOT`
is empty.

The reason for this error is complex:

- :mod:`lino.utils.dpy` must import the `.py` files provided by Django
  (by their file path). This is a quite tricky task. It does this
  using the `imp <https://docs.python.org/2/library/imp.html>`__
  package.

- When the :envvar:`DJANGO_SETTINGS_MODULE` is in a *settings package*
  (which is the case for many but not all demo projects), then the
  :attr:`project_dir <lino.core.site.Site.project_dir>` points to the
  :file:`settings` subdir of what we would intuitively consider the
  project directory.

- If we look at the code of :mod:`atelier.invlib` we can see the
  :cmd:`inv prep` command sets the current directory as follows::

    for mod in ctx.demo_projects:
        m = import_module(mod)
        p = m.SITE.site_dir or m.SITE.project_dir
        with cd(p):
            # run initdb_demo
            ...

  Using `m.SITE.site_dir or m.SITE.project_dir` as current directory
  is a bit dangerous because it causes magic effects.

Code changes:

- The :cmd:`inv prep` command now always runs in the
  :attr:`project_dir <lino.core.site.Site.project_dir>` and no longer
  depends on :setting:`LINO_CACHE_ROOT`.

- :class:`lino.utils.dpy.DpyDeserializer` now ignores fixtures whose
  source file is located in the current directory.