invenio icon indicating copy to clipboard operation
invenio copied to clipboard

RFC Move example apps docstring to README.rst

Open remileduc opened this issue 8 years ago • 19 comments

It may be useful and easier for users to have the information on how to run the example applications directly in the example folder.

Thus, when you are on github (or browsing the code locally) and you are viewing the examples folder, you can see the instructions and how to run the small example, instead of looking for it on readthedocs or look into the app.py file.

cc @inveniosoftware/developers

remileduc avatar Oct 18 '16 13:10 remileduc

See also my related past musings about:

  1. propagating example app's documentation into RTFD as we did e.g. in Flask-Menu;
  2. simplifying the number of example app's helper scripts via Makefile;

in https://github.com/inveniosoftware/invenio-deposit/pull/122#r79128189

Makefile would be basically a "runnable README", so to speak.

Whatever we choose, we could tag instructions with :start-after: # sphinxdoc-initdb like technique, which would make the documentation also nicely readable on RTFD.

tiborsimko avatar Oct 18 '16 16:10 tiborsimko

I like the idea of having the instructions inside the example_app.py - they are usually short and I can easily see what steps will be required to install this example app. On the other hand, moving those steps to an executable Makefile will have the same benefits (you can open the file to see what steps are needed to install the example app) and if it's an executable file, it will save some copy-pasting into the terminal, so :+1: for the Makefiles.

switowski avatar Oct 19 '16 06:10 switowski

I saw that we are using examples in some places already:

https://github.com/inveniosoftware/invenio-oauth2server/blob/master/examples/app.py

@tiborsimko Wouldn't be simple to propagate this doc to a specific section in our RTFD? (Perhaps I misunderstood your comment).

jbenito3 avatar Oct 19 '16 08:10 jbenito3

The reason for including README.rst is to help people see what's in the example when browsing the code on GitHub. There is a good example in Flask repo: https://github.com/pallets/flask/tree/master/examples/minitwit

jirikuncar avatar Oct 19 '16 08:10 jirikuncar

The reason for including README.rst is to help people see what's in the example when browsing the code on GitHub.

This is obviously the same with the Makefile-based approach, because any verbiage text that you would put into a README file for people to read, you would put the same in the beginning of the Makefile.

Makefile, as a "runnable README", has the same information carrying weight in my eyes. Moreover, it has one notable advantage, because it's runnable. Hence it's natural to "rerun" all the example app steps with Makefiles, it's easy to write integration tests for Makefile-based instructions. You don't have these advantages with README-plaintext-file based instructions, they tend to get outdated more easily.

Moreover, consider the unnecessary clutter we currently have, with the README-based approach: (example taken from invenio-search-ui)

README.rst
app-fixtures.sh
app.py
app-setup.sh
app-teardown.sh
data
requirements.txt

versus the cleaner Makefile based approach:

Makefile
app.py
data
requirements.txt

(In theory, the latter could also have a README file, but it's kind of unnecessary as per the presence of Makefile.)

tiborsimko avatar Oct 19 '16 08:10 tiborsimko

The README is for people that browse the repository and find the example. It can be very simple and just mention that you can run make command to build, prepare, run and clean the example. Sometimes we need to mention somewhere the need of configuring external services (e.g. installing Elasticsearch plugins). IMHO example app is not a documentation and it should help people to "play" with the module.

I'm not saying that we should not include Makefile, but the target audience of Makefile is different from the one that would like to see README.rst.

jirikuncar avatar Oct 19 '16 08:10 jirikuncar

The goal of the RFC is simply to help users to setup the example even if they know nothing about python, flask, bash... If you find a code with a README, you will read it because it is standard (and github print it by default). If you only find a Makefile, you'll have to open it, and you'll need the technical skills to understand it.

Finally, what you can do is a file README.sh with a comment at the begining saying "run me to launch the example" and eventually some other comments so it is well printed in Github, AND you can run it easily without any copy/paste.

example here: https://github.com/remileduc/invenio/tree/remileduc-patch-2/invenio

remileduc avatar Oct 19 '16 09:10 remileduc

README.sh

What a trick 🎩

jirikuncar avatar Oct 19 '16 09:10 jirikuncar

I'm not saying that we should not include Makefile, but the target audience of Makefile is different from the one that would like to see README.rst.

Consider a Makefile looking like:

# This is a minimal example application for Invenio-Records-UI.
#
# Prerequisites: Redis, SQlite.
#
# The example application demonstrates foo and bar. You can run xyzzy and zyxxy
# and see the output on http://0.0.0.0/records/1.
#
# ...

all:
   ...

Would having an extra README file be advantageous in this case? Isn't the verbiage at the start of Makefile enough?

That said, I'm not fully against including a minimal README either :smile: but I think it is not really necessary, because Makefile is a "runnable README" already. ("Less is more.")

I assume that people have a habit of reading a Makefile when they meet one... we are targetting developers, they should be already familiar with the concept.

Finally, what you can do is a file README.sh with a comment at the begining saying "run me to launch the example"

This approach would have the clutter disadvantage I mentioned above if you keep the tiny shell scripts for people to rerun the "populate" step or the "destroy" step more than once.

Unless you thought of using README.sh together with Makefile? In that case, we don't need README.sh, it would be more than enough to use a plain-text README or a formatted README.rst. These are more standard, and possibly easier to include "as is" into RTFD documentation.

If you only find a Makefile, you'll have to open it, and you'll need the technical skills to understand it.

Well, if a developer doesn't understand Makefiles yet, then it'll be a good investment for him/her to learn the concept :smile: Let's aim at using the right tool for the job. Frankly, the concept shouldn't be hard to understand:

# This is some help text.

all: build run init populate test

init:
    flask db init
    flask db create

populate:
    flask fixtures records

destroy:
    flask db drop

so it is well printed in Github

I reckon this was not my primary goal. I think that random visitors interested in an Invenio package would tend to browse our RTFD pages in order to learn more about the package, and Invenio developers would have the code checked out locally, so "browsing code directories on GitHub" wasn't of top concern to me.

Instead, I've been calling for taking advantage of this RFC to aim for more than that, notably (i) to propagate example instructions into RTFD, (ii) to declutter the source code base of the current tiny shell scripts, (iii) to enable easy rerunning of example app steps for smoother development and integration testing, and all this (iv) without having to repeat the either the information or the instruction steps in several places, if at all possible.

(We started these musings with @hachreak in https://github.com/inveniosoftware/invenio-deposit/pull/122 and this RFC seemed like a good place to take over and conclude on these thoughts...)

tiborsimko avatar Oct 19 '16 09:10 tiborsimko

I really don't want to lead the discussion to Makefile vs. README.rst. They can both co-exist and have their own audience. Moreover if we start with some more complex examples that have non trivial setup and requirements, then I see benefits for new developers in having README displayed when browsing the code on GitHub.

jirikuncar avatar Oct 19 '16 10:10 jirikuncar

Yes, I agreed above that README and Makefile aren't mutually exclusive, and both can be used. However, the decision about Makefiles influences the decision about READMEs. It seems advantageous to consider the two topics together, so that we don't have to redo things twice for all the 46 repositories that contain the example app...

tiborsimko avatar Oct 19 '16 10:10 tiborsimko

I reckon this was not my primary goal. I think that random visitors interested in an Invenio package would tend to browse our RTFD pages in order to learn more about the package, and Invenio developers would have the code checked out locally, so "browsing code directories on GitHub" wasn't of top concern to me.

As an example, yesterday I wanted to have a look at invenio-webhooks. I went to the repo and since there is no doc for usage/installation on RTD, first thing I did was to check the example. Just as my personal perception, I would have found it extremely confortable and convenient if there would have been a README.sh directly printed there. Then again, I can read the makefile :)

jbenito3 avatar Oct 19 '16 11:10 jbenito3

I went to the repo and since there is no doc for usage/installation on RTD [...]

This points to the core of the matter for me, and illustrates why I was calling for addressing RFTD at the same time. We don't have RTFD for many packages still, which is the ultimate goal before releasing Invenio 3.0 final... So @inveniosoftware/developers let's join I3B-API-Docs kanban to get there faster!

I would have found it extremely confortable and convenient if there would have been a README.sh directly printed there

I really wonder how frequent is the use case of "people-expecting-to-see-something-displayed-inline-when-browsing-GitHub-directories". How do people know that if they click on "examples" that they would get some help directly printed there? And where do we stop? Would people expect to click on "tests" directory to see a directly printed guide on how to run and write tests? Would they expect to click on "docs" and see direct link to RTFD? Would they expect to see a Transifex guide after clicking on "translations" directory? And what about clicking inside our source code directories? How many READMEs would we need to fit this "browsing around" use case?

In my eyes, all these "getting started" needs are better addressed in a more scalable way by (i) boot camp exposure to package structure for new developers (already being done, but IRL only), accompanied by (ii) currently subdocumented package anatomy, which we should further expand upon #3657 #3658. Richer documentation would address these needs in a more comprehensive manner.

Then again, I can read the makefile

... this is what I was thinking that a developer instinct would do. :smile: It's true that it's "one click away" when browsing GitHub, but is it really such a big deal?

P.S. Again, let me repeat that we could have both examples/README and examples/Makefile... I simply find it a bit redundant, especially if README is more or less going to point to Makefile...

tiborsimko avatar Oct 19 '16 12:10 tiborsimko

This points to the core of the matter for me, and illustrates why I was calling for addressing RFTD at the same time. We don't have RTFD for many packages still, which is the ultimate goal before releasing Invenio 3.0 final... So @inveniosoftware/developers let's join I3B-API-Docs kanban to get there faster!

👍

I really wonder how frequent is the use case of "people-expecting-to-see-something-displayed-inline-when-browsing-GitHub-directories". How do people know that if they click on "examples" that they would get some help directly printed there? And where do we stop? Would people expect to click on "tests" directory to see a directly printed guide on how to run and write tests? Would they expect to click on "docs" and see direct link to RTFD? Would they expect to see a Transifex guide after clicking on "translations" directory? And what about clicking inside our source code directories? How many READMEs would we need to fit this "browsing around" use case?

I simply said that I would find it more convenient...not that I would expect to find it there 😄 Actually, I would rather prefer to see more info directly from the README in the root of the repo. Which is what we want at the end of the day, right?

(ii) currently subdocumented package anatomy, which we should further expand upon #3657 #3658. Richer documentation would address these needs in a more comprehensive manner.

👍

... this is what I was thinking that a developer instinct would do. 😄 It's true that it's "one click away" when browsing GitHub, but is it really such a big deal?

I don't think so. Just less convenient than the first one 😃

jbenito3 avatar Oct 19 '16 12:10 jbenito3

How do people know that if they click on "examples" that they would get some help directly printed there?

They don't have to know they just hope that it's there 😆

It's true that it's "one click away" when browsing GitHub, but is it really such a big deal?

From UX point of view - yes. For a Python developer who never had to see a Makefile in his/her life because she never wrote a single line of code in language that needs to be compiled.

jirikuncar avatar Oct 19 '16 12:10 jirikuncar

From UX point of view - yes. For a Python developer who never had to see a Makefile in his/her life because she never wrote a single line of code in language that needs to be compiled.

:+1: Makefiles are indeed out of context in a Python project. And for non-python projects I rarely have found projects using directly Makefiles, unless they were very small ones. Most projects use automake/autoconf, so one would basically never look into a Makefile looking for documentation.

kaplun avatar Oct 19 '16 18:10 kaplun

They don't have to know they just hope that it's there :laughing:

Browsing around inside various GitHub directories, from "examples" to "docs" to " tests" to "translations" to dunno-wherever-else-inside-our-codebase, hoping to see some interactive help printed out automatically, doesn't constitute a very efficient information discovery technique to me :smile: I'd rather populate our "Package anatomy" parts of the documentation guide, so that people could find appropriate help in a centralised place and in an organised manner.

tiborsimko avatar Oct 19 '16 22:10 tiborsimko

Makefiles are indeed out of context in a Python project.

Please note we are talking example app instructions here, and these are shell commands, such as flask initdb. They are not Python commands. Makefile is a perfectly usable tool for automatising running shell commands of that sort.

If you want to see some use case examples in Python projects:

  • what I have in mind is akin to Sphinx's use of Makefiles, that we already have in each Invenio package anyway: https://github.com/inveniosoftware/invenio/blob/master/docs/Makefile
  • and I gave an example of pypa's warehouse before, to cite just one more example: https://github.com/pypa/warehouse/blob/master/Makefile

Let me try with a story, perhaps it can illustrate my thoughts better. Let us imagine that we have now introduced README.rst or README.sh, which gives:

README.sh
app-fixtures.sh
app.py
app-setup.sh
app-teardown.sh
data
requirements.txt

I would argue that we have an unnecessary clutter here, because the example app is small, and the helper shell scripts like app-teardown.sh are tiny, typically 1-2 liners only, such as: (illustrative example only)

$ cat app-teardown.sh
flask db drop

Say I don't like the additional clutter that this brings to the source code file tree. Wouldn't people be able to focus better on the example app without seeing all that additional clutter?

One way to address the clutter problem would be to "hide" these ultra tiny helper shell scripts inside README.sh as shell functions, for example:

$ cat README.sh

setup () {
   flask init
   flask create
}

populate () {
   flask fixtures records
}

teardown () {
   flask db drop
}

if [ "$1" = "setup" ]; then
    setup
elif [ "$1" = "populate" ]; then
    populate
else
  ...

This would give nicely uncluttered source tree:

README.sh
app.py
data
requirements.txt

and people would type:

$ ./README.sh setup
$ ./README.sh populate
$ firefox http://0.0.0.0/records/1
$ ./README.sh teardown

to run the example app. (If README.sh looks a bit weird here, let's imagine app.sh or run.sh or something; the exact name of the unified helper script is of secondary importance to the story.)

So far so good; the clutter is gone, the focus is back.

However, let's ponder how is this different from the Makefile approach? With a Makefile, we'd have similar content (with less boiler plate):

``` console` $ cat Makefile

setup: flask init flask create

populate: flask fixtures records

teardown: flask db drop


with similarly uncluttered files:

Makefile app.py data requirements.txt


with people typing similarly:

``` console
$ make setup
$ make populate
$ firefox http://0.0.0.0/records/1
$ make teardown

to run this example app.

The two examples are pretty similar, aren't they? In other words, aren't we simply "rediscovering" the standard Makefile facility, if we start from the README.sh approach first, using a plethora of tiny helper scripts, and if we try to unclutter the source code tree to hide away those unnecessary tiny helper scripts later?

(Moreover, let's imagine the additional goodies that using the standard Makefile tool would bring. For example, people could type make <TAB> <RET> to see all the available options, with auto-completed value of either setup, populate or teardown for them, thanks to the usual Makefile shell completion. Yes, we could write a dedicated shell completion snippet for README.sh too, but isn't this again a sign that illustrates my point about "reinventing" the Makefile wheel again?)

In my eyes, this use of Makefiles is pretty common in the Unix world. Makefile is useful not only to compile C programs and the like. See the Sphinx example, see various TeX examples... I would guess that most developers had come across examples of this kind during their exposure to Unix.

tiborsimko avatar Oct 19 '16 22:10 tiborsimko

@tiborsimko from your examples looks like README and Makefile are two exclusive options, but they can co-exist together.

Makefile
README
app.py
requirements.txt

I would go even one step further and introduce setup.py, which has working shell completion too and we can remove requirements.txt.

README
app.py
setup.py

jirikuncar avatar Oct 20 '16 06:10 jirikuncar