diff --git a/docs/.gitignore b/docs/.gitignore index 80bf00fe71172fbf91ef27b9def2e19e81d62d5b..dd78dd0d84d79db9656b40739c409378e2c7bfdb 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -5,3 +5,4 @@ apibuild.pyc *.html libvirt-api.xml libvirt-refs.xml +todo.html.in diff --git a/docs/Makefile.am b/docs/Makefile.am index 7fae40db83f62427f23cdf6407888a7ef18330b5..674c443f745497bf3c4a78b008940cc109ad4d64 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,6 +1,8 @@ ## Process this file with automake to produce Makefile.in SUBDIRS= schemas +PERL = perl + # The directory containing the source code (if it contains documentation). DOC_SOURCE_DIR=../src @@ -53,7 +55,7 @@ gif = \ architecture.gif \ node.gif -dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) +dot_html_in = $(notdir $(wildcard $(srcdir)/*.html.in)) todo.html.in dot_html = $(dot_html_in:%.html.in=%.html) patches = $(wildcard api_extension/*.patch) @@ -97,6 +99,22 @@ ChangeLog.html.in: ChangeLog.xml ChangeLog.xsl $(XSLTPROC) --nonet $(top_srcdir)/docs/ChangeLog.xsl $< > $@ \ || { rm $@ && exit 1; }; fi +todo.html.in: todo.pl + if [ -f todo.cfg ]; then \ + echo "Generating $@"; \ + $(PERL) $(srcdir)/$< > $@ \ + || { rm $@ && exit 1; }; \ + else \ + echo "Stubbing $@"; \ + echo "

Todo list

" > $@ ; \ + fi + +todo: + rm -f todo.html.in + $(MAKE) todo.html + +.PHONY: todo + %.png: %.fig convert -rotate 90 $< $@ @@ -153,7 +171,7 @@ clean-local: rm -f *~ *.bak *.hierarchy *.signals *-unused.txt *.html maintainer-clean-local: clean-local - rm -rf libvirt-api.xml libvirt-refs.xml + rm -rf libvirt-api.xml libvirt-refs.xml todo.html.in rebuild: api all diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in index bb9cd8e82e1812e8247a4d2d3c32f6c094a1102e..481507e670c117e51b63d3d5470a0df481cb8d74 100644 --- a/docs/sitemap.html.in +++ b/docs/sitemap.html.in @@ -275,6 +275,12 @@
  • Bug reports How and where to report bugs and request features +
  • Contact diff --git a/docs/todo.cfg-example b/docs/todo.cfg-example new file mode 100644 index 0000000000000000000000000000000000000000..a99c61ae4b18aea8aef6da66e54ab93e1f63cd59 --- /dev/null +++ b/docs/todo.cfg-example @@ -0,0 +1,26 @@ +bugzilla = { + #username = ...some email addr... + #password = ...some bz password... + server = https://bugzilla.redhat.com +} +query = { + product = Virtualization Tools + alias = libvirtTodo +} + +output = { + title = Todo list + blurb = <development mailing list. +If you intend to work on one of the items here, it is recommended to +add a comment to the corresponding bugzilla ticket to this effect. +This will reduce the risk of duplicated effort between developers. +It is also strongly recommended to mail the development mailing list +with proposals for new APIs & XML before fully implementing them, to +allow for early design review. +EOF +} diff --git a/docs/todo.pl b/docs/todo.pl new file mode 100755 index 0000000000000000000000000000000000000000..5db940fcaeb343f8353dfb1612be9bc8497748e8 --- /dev/null +++ b/docs/todo.pl @@ -0,0 +1,120 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use BZ::Client; +use BZ::Client::Bug; + +use Config::Record; + +my $cfg = Config::Record->new(file => "todo.cfg"); +my $server = $cfg->get("bugzilla/server", "https://bugzilla.redhat.com"); +my $username = $cfg->get("bugzilla/username"); +my $password = $cfg->get("bugzilla/password"); + +my $product = $cfg->get("query/product", "Virtualization Tools"); +my $todoalias = $cfg->get("query/todoalias", "libvirtTodo"); + +my $title = $cfg->get("output/title", undef); +my $blurb = $cfg->get("output/blurb", undef); + +$SIG{__DIE__} = sub { + my $err = shift; + if (UNIVERSAL::isa($err, "BZ::Client::Exception")) { + die "Unable to access bugzilla: " . $err->message; + } + die $err; +}; + +my $client = BZ::Client->new(url => $server, + user => $username, + password => $password); + +my $todo = BZ::Client::Bug->search($client, {'product' => $product, + 'alias' => $todoalias}); + +die "Cannot find bug alias 'libvirtTodo'" unless $#{$todo} > -1; +my $todoid = $todo->[0]->{'bug_id'}; +my $todosummary = $todo->[0]->{'short_desc'}; +$todosummary =~ s/^\s*RFE\s*:\s*//; +$todosummary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//; +$todosummary =~ s/^\s*Tracker\s*:\s*//; + +my $trackers = BZ::Client::Bug->search($client, {'product' => $product, + 'blocked' => $todoid }); + +my @trackers; + +foreach my $tracker (@{$trackers}) { + my $summary = $tracker->{'short_desc'}; + $summary =~ s/^\s*RFE\s*:\s*//; + $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//; + $summary =~ s/^\s*Tracker\s*:\s*//; + + push @trackers, { + id => $tracker->{'bug_id'}, + summary => $summary, + features => [], + }; +} + +foreach my $tracker (@trackers) { + my $features = BZ::Client::Bug->search($client, {'product' => $product, + 'blocked' => $tracker->{id}}); + + foreach my $feature (@{$features}) { + my $summary = $feature->{'short_desc'}; + $summary =~ s/^\s*RFE\s*:\s*//; + $summary =~ s/^\s*\[\s*RFE\s*\]\s*:?\s*//; + + push @{$tracker->{features}}, { + id => $feature->{'bug_id'}, + summary => $summary, + }; + } +} + +sub escape { + my $txt = shift; + $txt =~ s/&/&/g; + $txt =~ s//>/g; + return $txt; +}; + +print "\n"; +print "\n"; +print " \n"; +if (defined $title) { + print "

    ", &escape($title), "

    \n"; +} else { + print "

    ", &escape($todosummary), "

    \n"; +} +if (defined $blurb) { + print "

    \n"; + print $blurb; + print "

    \n"; +} +foreach my $tracker (sort { $a->{summary} cmp $b->{summary} } @trackers) { + next unless $#{$tracker->{features}} > 0; + + my $summary = &escape($tracker->{summary}); + my $id = $tracker->{id}; + print "

    $summary

    \n"; + print " \n"; +} + +print "

    \n"; +print " This page is automatically generated from ", &escape($todosummary), "\n"; +print "

    \n"; +print " \n"; +print "\n";