help-gnats
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Suggestions from a new GNATS/gnatsweb user


From: William M. (Mike) Miller
Subject: Suggestions from a new GNATS/gnatsweb user
Date: Tue, 14 Feb 2006 10:58:20 -0500

We've just switched to GNATS from a proprietary defect tracking
system, and I wanted to share some observations and suggested
changes that came out of that experience.  First, though, I'd
like to thank the GNATS team for the product; the transition
was as close to painless as I could have hoped for, and we're
very pleased with the outcome.

Let me begin by saying that we are a small (4-person),
geographically-distributed company.  Futhermore, we are the
only ones interacting directly with GNATS; our customers send
us free-form email about questions and problems, and we digest
that information before entering it into the defect tracking
system.  We use gnatsweb almost exclusively, the only exception
being a few canned queries that use query-pr directly; we don't
use the email interface to GNATS at all.  These factors
naturally affect what we need from GNATS and are different from
many other users, I'm sure.

All of the suggestions and changes below deal with gnatsweb.pl;
we found no issues at all with GNATS proper.  I'll describe them
in no particular order.  All diffs are against gnatsweb-4.00.
Some are included just to point out where the change would be
needed, because doing it "right" here was more work than I had
time to commit at the point I was making the change.

One caveat regarding these suggestions: although I've generally
included diffs for the changes I describe, my Perl skills are
pretty rudimentary, so take the code with a grain of salt.  (I
won't be offended at all if someone sends me a more Perl-esque
substitute for some bit or another. :-)

1. We use the Category field to separate PRs among our three
   products.  Nearly all of the support traffic is for one of
   those products, so it's very convenient to have the Category
   field default to that product.  However, gnatsweb goes out
   of its way to require the user to set the Category field
   explicitly for each new PR.  In the following patch I just
   commented out the offending code, but it would be nice if
   this were configurable in gnatsweb-site.pl.

*** 1081,1095 ****
          "</small></td><td>\n", $intro, "\n";

      if (fieldinfo($_, 'fieldtype') eq "enum")
      {
        # Force user to choose a category.
!       if ($_ eq $CATEGORY_FIELD)
!       {
!         push(@$values, "unknown") if (!grep /^unknown$/, @$values);
!         $default = "unknown";
!       }
        if ($_ eq $SUBMITTER_ID_FIELD)
        {
            $default = $global_prefs{$SUBMITTER_ID_FIELD} || '';
        }
        print popup_or_scrolling_menu($_, $values, $default),
--- 1081,1095 ----
          "</small></td><td>\n", $intro, "\n";

      if (fieldinfo($_, 'fieldtype') eq "enum")
      {
        # Force user to choose a category.
! #      if ($_ eq $CATEGORY_FIELD)
! #      {
! #        push(@$values, "unknown") if (!grep /^unknown$/, @$values);
! #        $default = "unknown";
! #      }
        if ($_ eq $SUBMITTER_ID_FIELD)
        {
            $default = $global_prefs{$SUBMITTER_ID_FIELD} || '';
        }
        print popup_or_scrolling_menu($_, $values, $default),
***************

2. We found the 4-line default height of all multitext fields
   (except Description in the Edit page) to be constraining.  It
   would be nice to be able to set the heights of different
   fields (in different pages) explicitly in gnatsweb-site.pl.
   In this patch, I've just made the Description and Notes
   fields ("Notes" is a locally-added multitext field) 8 lines
   high in both the Create and Edit pages.  (Note: the original
   code assumes that the Description field is named
   "Description", both for the height calculation and to
   determine where to put the list of attachments.  This should
   be done via a variable, as is the case with most field names,
   like $CATEGORY_FIELD in the preceding patch.  I just used the
   field names directly in this patch.)

*** 1102,1111 ****
--- 1102,1112 ----
              "</td>\n</tr>\n";
      }
      elsif (fieldinfo($_, 'fieldtype') eq "multitext")
      {
        my $rows = 4;
+       $rows = 8 if /Description|Notes/;
        print $q->textarea(-name=>$_,
                           -cols=>$textwidth,
                           -rows=>$rows,
                           -default=>$default),
              "</td>\n</tr>\n";
***************
*** 1604,1614 ****
        "</td>\n</tr>\n";
      }
      elsif (fieldinfo ($_, 'fieldtype') eq 'multitext')
      {
        my $rows = 4;
!       $rows = 8 if /Description/;
        $rows = 2 if /Environment/;
        print $q->textarea(-name=>$_,
                           -cols=>$textwidth,
                           -rows=>$rows,
                           -default=>$fields{$_}),
--- 1609,1619 ----
        "</td>\n</tr>\n";
      }
      elsif (fieldinfo ($_, 'fieldtype') eq 'multitext')
      {
        my $rows = 4;
!       $rows = 8 if /Description|Notes/;
        $rows = 2 if /Environment/;
        print $q->textarea(-name=>$_,
                           -cols=>$textwidth,
                           -rows=>$rows,
                           -default=>$fields{$_}),
***************

3. Although gnatsweb removes empty query fields in many of the
   links it displays, the ones that go through get_pr_url do
   not.  This affects, notably, the "view" and "edit" links in
   each row of query output, so the extra baggage can add up,
   especially for the result of an "advanced query", which will
   typically have lots of empty fields.

   (On a more global note, this URL is used in the return_url
   field, which allows an automatic return to the query results
   page after editing a PR on that page.  This mechanism is
   really wasteful of bandwidth, adding many, many KB to each
   query results page for all the return_url fields.  This
   really ought to be implemented by using a cookie, not by
   embedding the query in every link on the page!  If I get the
   time, I'm going to look into changing this into using
   cookies.)

*** 1311,1322 ****
  sub get_pr_url
  {
    my($cmd, $pr, $include_return_url) = @_;
    my $url = $q->url() . "?cmd=$cmd&database=$global_prefs{'database'}";
    $url .= "&pr=$pr" if $pr;
!   $url .= "&return_url=" . $q->escape($q->self_url())
!         if $include_return_url;
    return $url;
  }

  # Return a URL to edit the given pr.  See get_pr_url().
  #
--- 1312,1327 ----
  sub get_pr_url
  {
    my($cmd, $pr, $include_return_url) = @_;
    my $url = $q->url() . "?cmd=$cmd&database=$global_prefs{'database'}";
    $url .= "&pr=$pr" if $pr;
!   if ($include_return_url) {
!     my ($query_string) = $q->self_url();
!     # Remove empty fields
!     $query_string =~ s/(\w|-)+=;//g;
!     $url .= "&return_url=" . $q->escape($query_string);
!   }
    return $url;
  }

  # Return a URL to edit the given pr.  See get_pr_url().
  #
***************

4. There is an assumption in gnatsweb that the first field in
   the "responsible" configuration is a user id, so that a
   "mailto:"; can be constructed by appending $site_mail_domain
   to it.  That's not true in our configuration (for reasons
   that aren't worth getting into), and it's an unnecessary
   assumption in any case: the third "responsible" field is an
   email address, so if it's there, it ought to be used in the
   "mailto:";.  (Note that parse_responsible defaults
   $responsible_address to the person name, so a configuration
   in which the first field is, in fact, an email user id will
   still work the same after these changes.)

*** 1449,1459 ****

        # make links in various fields
        if ($_ =~ /responsible/i) {
          # values in the responsible field are likely to be bare usernames,
          # so mark_urls won't work on them.
!         $val = make_mailto($val);
        } elsif ($_ =~ /related-prs/i) {
           # make the Related-PRs field show links to the PRs
  # dtb - this is juniper specific, but i think it's a good field to have in
  # the dbconfig...
          $val =~ s{(\b|PR)(\d+)\b}{'<a
href="'.get_viewpr_url($2)."\">$1$2</a>"}egi;
--- 1454,1464 ----

        # make links in various fields
        if ($_ =~ /responsible/i) {
          # values in the responsible field are likely to be bare usernames,
          # so mark_urls won't work on them.
!         $val = make_mailto($val, $responsible_address{$val});
        } elsif ($_ =~ /related-prs/i) {
           # make the Related-PRs field show links to the PRs
  # dtb - this is juniper specific, but i think it's a good field to have in
  # the dbconfig...
          $val =~ s{(\b|PR)(\d+)\b}{'<a
href="'.get_viewpr_url($2)."\">$1$2</a>"}egi;
***************
*** 2141,2155 ****


  # takes a string, and turns it into a mailto: link
  # if it's not a full address, $site_mail_domain is appended first
  sub make_mailto {
!     my $string = shift;
!     if ($string !~ /@/) {
!       $string = qq*<a href="mailto:${string}${site_mail_domain}";>$string</a>*;
      } else {
!       $string = qq*<a href="mailto:$string";>$string</a>*;
      }
      return $string;
  }

  # takes a string, attempts to make urls, PR references and email
--- 2146,2162 ----


  # takes a string, and turns it into a mailto: link
  # if it's not a full address, $site_mail_domain is appended first
  sub make_mailto {
!     my $name = shift;
!     my $addr = shift || $name;
!     my $string;
!     if ($addr !~ /@/) {
!       $string = qq*<a href="mailto:${addr}${site_mail_domain}";>$name</a>*;
      } else {
!       $string = qq*<a href="mailto:$addr";>$name</a>*;
      }
      return $string;
  }

  # takes a string, attempts to make urls, PR references and email
***************
*** 2482,2492 ****
        }
        $fieldcontents = $q->escapeHTML($fieldcontents);
        $fieldcontents = nonempty($fieldcontents);

        if ($columns[$whichfield] =~ /responsible/i) {
!         $fieldcontents = make_mailto($fieldcontents);
        } else {
          # make urls and email addresses into live hrefs
          $fieldcontents = mark_urls($fieldcontents);
        }

--- 2489,2500 ----
        }
        $fieldcontents = $q->escapeHTML($fieldcontents);
        $fieldcontents = nonempty($fieldcontents);

        if ($columns[$whichfield] =~ /responsible/i) {
!         $fieldcontents = make_mailto($fieldcontents,
!                                      $responsible_address{$fieldcontents});
        } else {
          # make urls and email addresses into live hrefs
          $fieldcontents = mark_urls($fieldcontents);
        }

***************

5. Query output can get very wide if you include a number of
   fields.  Dates are a major contributor; gnatsweb displays
   them with times and UTC deltas.  We don't need that level of
   detail in query output, given the relatively low volume of
   traffic that we handle; the day a PR arrived or was closed is
   really sufficient.  The format used to display dates in query
   output should be configurable in gnatsweb-site.pl.  In the
   following patch, I've just changed the format directly to
   reduce the clutter.

*** 2345,2355 ****
    # fields in the query output. Note that the format strings are
    # interpolated (quoted with ""'s), so make sure to escape any $ or @
    # signs.
    foreach (@columns) {
        if (fieldinfo ($_, 'fieldtype') eq 'date') {
!       $format .= "\037%{%Y-%m-%d %H:%M:%S %Z}D";
        } elsif (fieldinfo ($_, 'fieldtype') eq 'enum') {
        $format .= "\037%d";
        } else {
        $format .= "\037%s";
      }
--- 2352,2362 ----
    # fields in the query output. Note that the format strings are
    # interpolated (quoted with ""'s), so make sure to escape any $ or @
    # signs.
    foreach (@columns) {
        if (fieldinfo ($_, 'fieldtype') eq 'date') {
!       $format .= "\037%{%Y-%m-%d}D";
        } elsif (fieldinfo ($_, 'fieldtype') eq 'enum') {
        $format .= "\037%d";
        } else {
        $format .= "\037%s";
      }
***************

6. There is a bug in gnatsweb-4.00 that causes some stored
   queries (notably "advanced queries") not to work.  The
   reason is that the regular expression used to eliminate
   empty query fields in the cookie is defective, not allowing
   for "-" in field names.  This affects advanced queries in
   particular because the date fields are at the beginning of
   the query URL and the field names for the dates typically
   include "-" characters.

*** 2584,2594 ****
    my $query_string = $q->query_string();

    # strip empty params out of $query_string.  in a gnats db with many
    # fields, the query-string will become very long, and may exceed the
    # 4K limit for cookies.
!   $query_string =~ s/\w+=;//g;

    if (length($query_string . $global_cookie_path .
"gnatsweb-query-$queryname") > 4050) {
      # this cookie is going to be longer than 4K, so we'll have to punt
      error_page('Cannot store query -- cookie too large',
                 "Gnatsweb cannot store this query as a cookie because"
--- 2592,2602 ----
    my $query_string = $q->query_string();

    # strip empty params out of $query_string.  in a gnats db with many
    # fields, the query-string will become very long, and may exceed the
    # 4K limit for cookies.
!   $query_string =~ s/(\w|-)+=;//g;

    if (length($query_string . $global_cookie_path .
"gnatsweb-query-$queryname") > 4050) {
      # this cookie is going to be longer than 4K, so we'll have to punt
      error_page('Cannot store query -- cookie too large',
                 "Gnatsweb cannot store this query as a cookie because"
***************

7. Because we're a small company and only the four of us are
   accessing GNATS, we don't use the "full name" fields in
   submitters and responsible (we know each other by first name
   :-).  However, the trailing "-" that results from this
   configuration is unesthetic.

*** 3271,3281 ****
    foreach $_ (sort @lines)
    {
      my($submitter, $fullname, $type, $response_time, $contact, $notify)
            = split(/:/);
      push(@submitter_id, $submitter);
!     $submitter_complete{$submitter} = $submitter .' - ' . $fullname;
      $submitter_contact{$submitter} = $contact;
      $submitter_notify{$submitter} = $notify;
    }
  }

--- 3279,3290 ----
    foreach $_ (sort @lines)
    {
      my($submitter, $fullname, $type, $response_time, $contact, $notify)
            = split(/:/);
      push(@submitter_id, $submitter);
!     $submitter_complete{$submitter} = $submitter;
!     $submitter_complete{$submitter} .= ' - ' . $fullname if $fullname;
      $submitter_contact{$submitter} = $contact;
      $submitter_notify{$submitter} = $notify;
    }
  }

***************
*** 3291,3302 ****

    foreach $_ (sort @lines)
    {
      my($person, $fullname, $address) = split(/:/);
      push(@responsible, $person);
!     $responsible_fullname{$person} = $fullname;
!     $responsible_complete{$person} = $person . ' - ' . $fullname;
      $responsible_address{$person} = $address || $person;
    }
  }

  # initialize -
--- 3300,3312 ----

    foreach $_ (sort @lines)
    {
      my($person, $fullname, $address) = split(/:/);
      push(@responsible, $person);
!     $responsible_fullname{$person} = $fullname || $person;
!     $responsible_complete{$person} = $person;
!     $responsible_complete{$person} .= ' - ' . $fullname if $fullname;
      $responsible_address{$person} = $address || $person;
    }
  }

  # initialize -
***************

8. I wasn't sufficiently motivated to change this, but there's
   an annoying assumption regarding regular expressions for
   enumeration values in the following code:

      # Most (?) people expect queries on enums to be of the
      # exact, not the substring type.
      # Hence, provide explicit anchoring for enums. This
      # still leaves the user the possibility of inserting
      # ".*" before and/or after regular expression searches
      # on the advanced query page.
      if (fieldinfo($field, 'fieldtype') =~ "enum|multienum")
      {
        $subexp = appendexpr ($subexp, '|', "$field~\"^$sval\$\"");
      }
      else
      {
        $subexp = appendexpr ($subexp, '|', "$field~\"$sval\"");
      }

   We aren't among the "most (?) people," apparently.  We have
   defined the enumeration for Priority to have values like
   "1 - showstopper", "2 - urgent", "3 - important", etc., so
   we'd like to use a regular expression like "[12]" to match
   high-priority PRs and not have to type "[12].*".  We've set
   "query-default inexact-regexp" in dbconfig for the Priority
   field, but gnatsweb ignores it.  Either gnatsweb should
   honor that setting or it ought to be possible to override
   this assumption about enumerated fields by a setting in
   gnatsweb-site.pl.

Well, that's it.  I hope someone finds this helpful.  If I get
around to coding up the change to use a cookie instead of
return_url, I'll post that diff, too.

--
William M. (Mike) Miller | Edison Design Group
address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]