aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README14
-rw-r--r--README.cli19
-rwxr-xr-xupdate164
3 files changed, 185 insertions, 12 deletions
diff --git a/README b/README
index b084a49..5ee7acf 100644
--- a/README
+++ b/README
@@ -85,9 +85,9 @@ infrastructure).
Further, labels can be used to group notes based on certain criteria. For
example, doc (documentation issue), windows (Windows-specific), 2.0.0
(scheduled for the 2.0.0 release), 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
-lihello/format/, then its labels would be bug, format, and libhello.
+subdirectories in which the note is located are also considered its labels. So,
+for example, if the above "Detect empty name" bug was filed in lihello/format/,
+then its labels would be bug, format, and libhello.
The body of a note is free-form. However, for clarity, it makes sense to avoid
using '-' for lists in the body ('*' for the first level and '~' for the second
@@ -158,8 +158,8 @@ For example:
Add bug: Detect empty name
-If you only have a single issue added in the database then you can use the add
-script to automate it. This script will commit the new issues with the correct
+If you only have a single note added in the database then you can use the add
+script to automate this. This script will commit the new note with the correct
message and, unless the -c option is specified, push the result to origin. This
should make filing new notes a fairly burdenless process: write a note using
your favorite text editor and run the add script. Note that the add script
@@ -174,6 +174,10 @@ For example:
Update idea: Implement pluggable formatter
+Similar to adding, if you only have a single note updated in the database then
+you can use the update script to automate this. Note that the update script
+currently cannot handle updates with extra files.
+
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
diff --git a/README.cli b/README.cli
index 2ca9e55..d61e868 100644
--- a/README.cli
+++ b/README.cli
@@ -107,7 +107,7 @@ a new feature), \c{quality} (improve quality of implementation), \c{infra}
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
+names of subdirectories in which the note 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}.
@@ -189,12 +189,13 @@ 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 only have a single note added in the database then you can use the
+\c{add} script to automate this. This script will commit the new note 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:
@@ -209,6 +210,10 @@ For example:
Update idea: Implement pluggable formatter
\
+Similar to adding, if you only have a single note updated in the database then
+you can use the \c{update} script to automate this. Note that the \c{update}
+script currently cannot handle updates with extra files.
+
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
diff --git a/update b/update
new file mode 100755
index 0000000..fc2ba54
--- /dev/null
+++ b/update
@@ -0,0 +1,164 @@
+#! /usr/bin/env bash
+
+# Commit and push an update to an existing note.
+#
+# -c
+# Commit only, don't push.
+#
+usage="usage: $0 [-c]"
+
+owd=`pwd`
+trap "{ cd $owd; exit 1; }" ERR
+set -o errtrace # Trap in functions.
+
+function info () { echo "$*" 1>&2; }
+function error () { info "$*"; exit 1; }
+
+push="y"
+
+while [ $# -gt 0 ]; do
+ case $1 in
+ -c)
+ push="n"
+ shift
+ ;;
+ *)
+ error "$usage"
+ ;;
+ esac
+done
+
+if git status --porcelain | grep -q '^M '; then
+ error "error: repository already has staged changes"
+fi
+
+# @@ We could probably handle the case where extra files are added to the
+# note. We just need to make sure they are not changes to other notes.
+#
+if git status --porcelain | grep -q '^?? '; then
+ error "error: repository has untracked files"
+fi
+
+modified="$(git status --porcelain | sed -n -e 's/^ M \(.*\)/\1/p')"
+
+mc="$(echo "$modified" | wc -w)"
+
+if [ "$mc" -eq 0 ]; then
+ error "error: nothing modified"
+fi
+
+if [ "$mc" -gt 1 ]; then
+ error "error: multiple modified files"
+fi
+
+# Extract the start line and count from the changeset header.
+#
+# The format is:
+#
+# @@ [+-]FROM-START,FROM-COUNT [+-]TO-START,TO-COUNT @@
+#
+# Note that if the changeset has only one line then the count is omitted.
+#
+function changeset_start ()
+{
+ echo "$1" | sed -e 's/^@@ [^ ]* [+-]\([^, ]*\).*$/\1/'
+}
+
+function changeset_count ()
+{
+ local r
+ r="$(echo "$1" | sed -n -e 's/^@@ [^ ]* [+-][^,]*,\([^ ]*\) @@$/\1/p')"
+ if [ -z "$r" ]; then
+ r="1"
+ fi
+ echo "$r"
+}
+
+#changeset_start "@@ -12,3 +13,11 @@"
+#changeset_count "@@ -12,3 +13,11 @@"
+#changeset_start "@@ -12 +13 @@"
+#changeset_count "@@ -12 +13 @@"
+
+h=
+if [ "$(basename "$modified")" = "list" ]; then
+ #
+ # This is a list of notes. The plan is to get the start line numbers for the
+ # first and last change set. We then scan the list line by line looking for
+ # headers until we hit the start of the first change set: the last header
+ # that we see should be our header. We also continue scanning until we hit
+ # the end of the last changeset: if we see any headers then we are updating
+ # multiple notes.
+ #
+
+ # Get the diff output as a list of change set headers.
+ #
+ diff="$(git diff -U0 | sed -n -e '/^@@ /p')"
+
+ fc="$(echo "$diff" | head -n 1)"
+ lc="$(echo "$diff" | tail -n 1)"
+
+ sl="$(changeset_start "$fc")"
+ el="$(($(changeset_start "$lc") + $(changeset_count "$lc") - 1))"
+
+ # Scan the list looking for headers.
+ #
+ l=
+ c="0"
+ while read l || [ -n "$l" ]; do
+
+ # Stop if we are past the end line.
+ #
+ c="$(($c + 1))"
+ if [ "$c" -gt "$el" ]; then
+ break
+ fi
+
+ # See if this is a header.
+ #
+ if echo "$l" | grep -q '^[-?!] '; then
+
+ # If we are past the start line then we are modifying multiple notes.
+ #
+ if [ "$c" -gt "$sl" ]; then
+ error "error: multiple modified notes in $modified:${sl}-${el}"
+ fi
+
+ # This is the last header.
+ #
+ h="$l"
+ fi
+ done < <(cat "$modified")
+
+ if [ -z "$h" ]; then
+ error "error: unable to find note header for $modified:${sl}-${el}"
+ fi
+else
+ # This is a file note. All we need to do is get its header (the first line).
+ #
+ h="$(head -n 1 "$modified")"
+fi
+
+# Header should start with one of [-?!].
+#
+sum="$(echo "$h" | sed -n -re 's/^[-?!] ([^[]*)( \[.*\])?$/\1/p')"
+
+if [ -z "$sum" ]; then
+ error "error: unable to parse note header '$h'"
+fi
+
+# By convention the first label is a note type (bug, feature, etc).
+#
+type="$(echo "$h" | sed -n -re 's/^[^[]*\[([^ ]*).*\]$/\1/p')"
+
+if [ -z "$type" ]; then
+ error "error: note header does not include note type as first label"
+fi
+
+# Ok, all looks good so add, commit and push the change.
+#
+git add "$modified"
+git ci -m "Update $type: $sum"
+
+if [ "$push" = "y" ]; then
+ git push
+fi