// cli --generate-txt --txt-suffix "" README.cli // @@ add -n which prints the tree, asks for where to add (auto-completion) // and starts the editor. // // @@ drop script? // // @@ impl script? Don't even need to extract anything. Or maybe should to // make sure the commit message is the same. Could warn if doesn't match // subject. Not going to be easy if moved. " Version 1.0 This document describes the \i{change development} database and process. The main premise of the approach described here is that planning changes in code should be handled in the same way as changing the code itself; that is, using \c{git(1)} and our favorite text editors, rather than some external database accessible via a web interface (which what most bug trackers are these days). To be usable, the database format and process must not be burdensome. As a result, there is minimum notation as well as helper tools to automate common operations, for example, adding a new item (called a note). The database can either be stored in the \c{git} repository of the project itself or, if the project consists of multiple \c{git} repositories, in a repository of its own. In the former case it is recommended to place the database in the top-level subdirectory of a project and call it \c{change}. In the latter case it is recommended to call the repository \c{change}, potentially with a prefix denoting the overall project name, for example, \c{hello-change}. The change database is a collection of notes stored in plain text files that use a certain notation. The files are organized in subdirectories which are used to group notes that affect a certain subproject or an area of a project. For a database that covers multiple \c{git} repositories it is common to have top-level subdirectories named after those repositories. As an example, let's say we have a \"Hello, World!\" project that consists of two git repositories: the \c{libhello} library and the \c{hello} program. The resulting directory structure then could be: \ hello/ libhello/ change/ | |--hello/ | `--libhello/ \ Continuing with this example, inside \c{libhello/} we could have subdirectories for major functionality areas: \ change/ | |--hello/ | `--libhello/ | |--format/ | `--print/ \ It seldom makes sense to have more than two levels of subdirectories. At the top level the subdirectory called \c{reference} is reserved for storing notes that have been acted upon. Its usage is described in more detail below. A note consists of a \i{header} and an optional \i{body} separated with a blank line. All lines in a note should be no longer than 78 characters. The header is always the first line and contains the note's \i{severity}, \i{summary}, and optional \i{labels}. The header has the following format (literal values are quoted): \ ['-'|'!'|'?'|'+'] <summary>[ '['<label>[ <label>]...']'] \ For example: \ ! Detect empty name [bug] - Add ability to customize greeting phrase [feature 2.0.0] ? Implement pluggable formatter [idea] \ The '\c{-}' severity denotes a normal note, '\c{!}' \- critical, and '\c{?}' \- unconfirmed or questionable, while '\c{+}' is used to denote implemented notes in the \c{reference} directory (discussed below). The summary should follow the \c{git} rules for a commit message summary, that is, it should use no articles, past/future tenses, and should ideally be no longer than 60 characters (though this rule can sometimes be broken for clarity). Normally, you should be able to copy the summary into the commit message when you have implemented a note. Labels are separated with a space (note: not a comma and space). By convention the first label should be the note type. Commonly used types are: \c{bug} (fix something broken), \c{feature} (implement new functionality), \c{idea} (design a new feature), \c{quality} (improve quality of implementation), \c{infra} (work on project infrastructure). Further, labels can be used to group notes based on certain criteria. For example, \c{doc} (documentation issue), \c{windows} (Windows-specific), \c{2.0.0} (scheduled for the 2.0.0 release), \c{john} (assigned to John). The names of subdirectories in which the issue is located are also considered its labels. So, for example, if the above \"Detect empty name\" bug was filed in \c{lihello/format/}, then its labels would be \c{bug}, \c{format}, and \c{libhello}. The body of a note is free-form. However, for clarity, it makes sense to avoid using '\c{-}' for lists in the body ('\c{*}' for the first level and '\c{~}' for the second level are good options). Notes can be saved in three ways. Simple notes without a body or with a body containing one or two paragraphs can be written in the \c{list} files. These files can appear at the top level or in any subdirectory. More complex notes can be placed in their own files. Finally, notes that have addition material (what traditional bug trackers would call \"attachments\") should be placed into their own subdirectories with both the directory and the note file (inside that subdirectory) having the same name. Other than that, such a subdirectory is free form; it can contain other files and subdirectories. If a note is written in the \c{list} file, then its body must be indented two spaces to align with the start of the summary. Notes are separated with blank lines and their order in the \c{list} files is not significant. Normally you would add a new note at the top, for convenience. Continuing with our example, let's file our bug and idea in the \c{list} file under \c{libhello/format/} (since they both only affect this functionality): \ ! Detect empty name [bug] It would make sense to detect empty names and throw invalid_argument. ? Implement pluggable formatter [idea] Some users asked for a way to provide their own formatting implementation via some sort of a plugin mechanism. Note that it's not clear at all this is a good idea. \ If a note is written into its own file then its body need not be indented; everything after the header and the blank like is just a normal plain text file. When choosing a name for a file try to incorporate at least two and preferably three keywords form the summary. This will minimize the chance of a name conflict in the reference directory which will accumulate notes over many years. As an example, let's save our feature into \c{custom-greeting-phrase} under \c{libhello/}: \ - Add ability to customize greeting phrase [feature 2.0.0] Some users asked for a way to customize the greeting phrase. For example, some prefer less formal \"Hi\" to \"Hello\". The way we can implement this is by adding greeting as the second argument to say() that will default to \"Hello\". Note that this change will be source but not binary compatible so we will have to bump at least the minor version. \ Note also that we can move notes freely between files. For example, we may add a new subdirectory and move all the notes that affect this functionality from the top-level \c{list} file. Or we can move a note from \c{list} to its own file or from a file to a subdirectory if we need to keep some additional files with the note. For example, if we start expanding on our \"Implement pluggable formatter\" idea, then it probably makes sense to move it into its own file. When committing (in the \c{git} sense) changes to the database, use a separate commit for each note. When committing a newly added note, the commit message should be in the form: \ Add <type>: <summary> \ For example: \ Add bug: Detect empty name \ If you only have a single issue added in the database then you can use the \c{add} script to automate it. This script will commit the new issues with the correct message and, unless the \c{-c} option is specified, push the result to \c{origin}. This should make filing new notes a fairly burdenless process: write a note using your favorite text editor and run the \c{add} script. Note that the \c{add} script currently cannot handle notes with extra files. If you change an existing note (for example, add additional information), then the commit message should have the following form: \ Update <type>: <summary> \ For example: \ Update idea: Implement pluggable formatter \ Once a note is acted upon (implemented or you have decided not to do anything about it), you can either delete it or move it to the reference. Simply deleting a note is appropriate for simple bugs and features where all the design information, if any, is incorporated into the code itself. For a more elaborate note, however, it may make sense to preserve it in case it needs to be revisited in the future. The top-level \c{reference} subdirectory should recreate the same directory structure as top-level (except for \c{reference/} itself). For instance, this will be the structure for our example: \ change/ | |--hello/ | |--libhello/ | | | |--format/ | | | `--print/ | `--reference/ | |--hello/ | `--libhello/ | |--format/ | `--print/ \ Only notes stored as separate files can be moved to the reference (in other words, there should be no \c{list} files in \c{reference/}). When moved, a note should be placed into the corresponding subdirectory and its severity changed to either '\c{+}' if it has been implemented or to '\c{?}' if it has been dropped (in which case it is a good idea to add an explanation as to why). Continuing with our example, let's say we have implemented the \"Customize Greeting Phrase\" feature but would like to keep the note. This is the relevant part of our directory structure before the move: \ change/ | |--libhello/ | | | `--custom-greeting-phrase | `--reference/ | `--libhello/ \ And this is after the move (we also change the severity to '\c{+}' inside \c{custom-greeting-phrase}): \ change/ | |--libhello/ | `--reference/ | `--libhello/ | `--custom-greeting-phrase \ For an implemented note the commit message should be the same as the one for the implementation in the code repository and which normally should be the same as the note subject. If the change database is part of the project's \c{git} repository, then everything should be in the same commit. If you have decided not to implement a note, then the commit message should have the following form: \ Drop <type>: <summary> \ For example: \ Drop idea: Implement pluggable formatter \ "