From: Jakub Narebski <jnareb@gmail.com>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: "J.H." <warthog9@kernel.org>,
Jonathan Nieder <jrnieder@gmail.com>,
git@vger.kernel.org, admin@repo.or.cz
Subject: [RFC/PATCH] gitweb: Change the way "content tags" ('ctags') are handled
Date: Mon, 7 Mar 2011 19:00:13 +0100 [thread overview]
Message-ID: <201103071900.16126.jnareb@gmail.com> (raw)
In-Reply-To: <20110303081904.GM22310@pengutronix.de>
On Thu, 3 March 2011, Uwe Kleine-König wrote:
> On Thu, Mar 03, 2011 at 01:42:15AM +0100, Jakub Narebski wrote:
>> On Wed, 2 Mar 2011, Uwe Kleine-König wrote:
>>> On Wed, Mar 02, 2011 at 10:18:44PM +0100, Jakub Narebski wrote:
>>>> What is most important that makes this feature to be considered for
>>>> removal (or rehauling) is that only half of this feature is implemented
>>>> in gitweb: the displaying part. There is half-attempt of providing
>>>> some web interface for managing tags... which needs external script with
>>>> strict coupling, doesn't offer any access control as far as I know, do
>>>> not allow deleting tags, etc.
>>>
>>> For a small set of repositories the need to hand-edit the tags is OK
>>> IMHO. That's what I intended to do.
>>
>> So what would you like to see?
>>
>> 1. Hardening parsing of ctags files, so that gitweb does not crash on
>> malformed entries, but e.g. just ignores them.
Done.
>> 2. Generating tag cloud upfront, before sending any output to browser,
>> to catch error better (and perhaps separate CSS for HTML::TagCloud).
Not done, but with 1. it should be not very necessary... unless another
bug is found in related code, that is.
>> 3. Describe format of ctags files, either in comments in code, or in
>> gitweb/README.
Done (comments in code).
>> 4. Either:
>>
>> A. Remove editing ctags from gitweb, or
>> B. Add some simple generation of ctags file to gitweb
Done 4.A.
> yes :-) (1-3, 4a) I wouldn't mind 4b, but it should be possible to
> disable the possibility to publically edit tags via gitweb.
The patch below (addressing those issues) is based on
"[PATCHv2/RFC] gitweb: Restructure projects list generation"
http://thread.gmane.org/gmane.comp.version-control.git/167996/focus=168321
http://repo.or.cz/w/git/jnareb-git.git/commit/420071752d13dcecd59e794d82285e7e142ef75f
('gitweb/web' branch in http://repo.or.cz/w/git/jnareb-git.git repository)
-- >8 --
Subject: [RFC/PATCH] gitweb: Change the way "content tags" ('ctags') are handled
The major change is removing the ability to edit content tags (ctags)
in a web browser.
The interface was created by gitweb, while actual editing of tags was
to be done by external script; the API was not defined, and neither
was provided example implementation. Such split is also a bit fragile
- interface and implementation have to be kept in sync. Gitweb
provided only ability to add tags; you could not edit tags nor delete
them.
Format of ctags is now described in the comment above git_get_project_ctags
subroutine. Gitweb now is more robust with respect to original ctags
format; it also accepts two new formats: $GIT_DIR/ctags file, with one
content tag per line, and multi-value `gitweb.ctag' config variable.
Gathering all ctags of all project is now put in git_gather_all_ctags
subroutine, making git_project_list_body more clear.
git_populate_project_tagcloud subroutine now generates data used for
tag cloud, including generation of ctag link, also in the case
HTML::TagCloud module is unavailable. Links are now generated using
href() subroutine - this is more robust, as ctags might contain '?',
';' and '=' special characters that need to be escaped in query param.
Shown tags are HTML-escaped.
The generation of tag cloud in git_show_project_tagcloud in the case
when HTML::TagCloud is not available is now changed slightly.
The 'content tags' field on project summary page is made more in line
with other fields in "projects_list" table. Because one cannot now
add new tags from web interface, this field is no longer displayed
when there are no content tags for given project.
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
gitweb/gitweb.perl | 141 +++++++++++++++++++++++++++++++++++----------------
1 files changed, 97 insertions(+), 44 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 996b647..4d80818 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -412,20 +412,23 @@ our %feature = (
'override' => 0,
'default' => []},
- # Allow gitweb scan project content tags described in ctags/
- # of project repository, and display the popular Web 2.0-ish
- # "tag cloud" near the project list. Note that this is something
- # COMPLETELY different from the normal Git tags.
+ # Allow gitweb scan project content tags of project repository,
+ # and display the popular Web 2.0-ish "tag cloud" near the projects
+ # list. Note that this is something COMPLETELY different from the
+ # normal Git tags.
# gitweb by itself can show existing tags, but it does not handle
- # tagging itself; you need an external application for that.
- # For an example script, check Girocco's cgi/tagproj.cgi.
+ # tagging itself; you need to do it externally, outside gitweb.
+ # The format is described in git_get_project_ctags() subroutine.
# You may want to install the HTML::TagCloud Perl module to get
# a pretty tag cloud instead of just a list of tags.
# To enable system wide have in $GITWEB_CONFIG
- # $feature{'ctags'}{'default'} = ['path_to_tag_script'];
+ # $feature{'ctags'}{'default'} = [1];
# Project specific override is not supported.
+
+ # In the future whether ctags editing is enabled might depend
+ # on the value, but using 1 should always mean no editing of ctags.
'ctags' => {
'override' => 0,
'default' => [0]},
@@ -703,6 +706,7 @@ our @cgi_param_mapping = (
snapshot_format => "sf",
extra_options => "opt",
search_use_regexp => "sr",
+ ctag => "by_tag",
# this must be last entry (for manipulation from JavaScript)
javascript => "js"
);
@@ -2564,23 +2568,66 @@ sub git_get_project_description {
return $descr;
}
+# supported formats:
+# * $GIT_DIR/ctags/<tagname> file (in 'ctags' subdirectory)
+# - if its contents is a number, use it as tag weight,
+# - otherwise add a tag with weight 1
+# * $GIT_DIR/ctags file, each line is a tag (with weight 1)
+# the same value multiple times increases tag weight
+# * `gitweb.ctag' multi-valued repo config variable
sub git_get_project_ctags {
- my $path = shift;
+ my $project = shift;
my $ctags = {};
- $git_dir = "$projectroot/$path";
- opendir my $dh, "$git_dir/ctags"
- or return $ctags;
- foreach (grep { -f $_ } map { "$git_dir/ctags/$_" } readdir($dh)) {
- open my $ct, '<', $_ or next;
- my $val = <$ct>;
- chomp $val;
- close $ct;
- my $ctag = $_; $ctag =~ s#.*/##;
- $ctags->{$ctag} = $val;
+ $git_dir = "$projectroot/$project";
+ if (opendir my $dh, "$git_dir/ctags") {
+ my @files = grep { -f $_ } map { "$git_dir/ctags/$_" } readdir($dh);
+ foreach my $tagfile (@files) {
+ open my $ct, '<', $tagfile
+ or next;
+ my $val = <$ct>;
+ chomp $val if $val;
+ close $ct;
+
+ (my $ctag = $tagfile) =~ s#.*/##;
+ if ($val =~ /\d+/) {
+ $ctags->{$ctag} = $val;
+ } else {
+ $ctags->{$ctag} = 1;
+ }
+ }
+ closedir $dh;
+
+ } elsif (open my $fh, '<', "$git_dir/ctags") {
+ while (my $line = <$fh>) {
+ chomp $line;
+ $ctags->{$line}++ if $line;
+ }
+ close $fh;
+
+ } else {
+ my $taglist = config_to_multi(git_get_project_config('ctag'));
+ foreach my $tag (@$taglist) {
+ $ctags->{$tag}++;
+ }
}
- closedir $dh;
- $ctags;
+
+ return $ctags;
+}
+
+# return hash, where keys are content tags ('ctags'),
+# and values are sum of weights of given tag in every project
+sub git_gather_all_ctags {
+ my $projects = shift;
+ my $ctags = {};
+
+ foreach my $p (@$projects) {
+ foreach my $ct (keys %{$p->{'ctags'}}) {
+ $ctags->{$ct} += $p->{'ctags'}->{$ct};
+ }
+ }
+
+ return $ctags;
}
sub git_populate_project_tagcloud {
@@ -2600,31 +2647,41 @@ sub git_populate_project_tagcloud {
my $cloud;
if (eval { require HTML::TagCloud; 1; }) {
$cloud = HTML::TagCloud->new;
- foreach (sort keys %ctags_lc) {
+ foreach my $ctag (sort keys %ctags_lc) {
# Pad the title with spaces so that the cloud looks
# less crammed.
- my $title = $ctags_lc{$_}->{topname};
+ my $title = esc_html($ctags_lc{$ctag}->{topname});
$title =~ s/ / /g;
$title =~ s/^/ /g;
$title =~ s/$/ /g;
- $cloud->add($title, $home_link."?by_tag=".$_, $ctags_lc{$_}->{count});
+ $cloud->add($title, href(project=>undef, ctag=>$ctag),
+ $ctags_lc{$ctag}->{count});
}
} else {
- $cloud = \%ctags_lc;
+ $cloud = {};
+ foreach my $ctag (keys %ctags_lc) {
+ my $title = $ctags_lc{$ctag}->{topname};
+ $cloud->{$ctag}{count} = $ctags_lc{$ctag}->{count};
+ $cloud->{$ctag}{ctag} =
+ $cgi->a({-href=>href(project=>undef, ctag=>$ctag)},
+ esc_html($title, -nbsp=>1));
+ }
}
- $cloud;
+ return $cloud;
}
sub git_show_project_tagcloud {
my ($cloud, $count) = @_;
- print STDERR ref($cloud)."..\n";
if (ref $cloud eq 'HTML::TagCloud') {
return $cloud->html_and_css($count);
} else {
- my @tags = sort { $cloud->{$a}->{count} <=> $cloud->{$b}->{count} } keys %$cloud;
- return '<p align="center">' . join (', ', map {
- $cgi->a({-href=>"$home_link?by_tag=$_"}, $cloud->{$_}->{topname})
- } splice(@tags, 0, $count)) . '</p>';
+ my @tags = sort { $cloud->{$a}->{'count'} <=> $cloud->{$b}->{'count'} } keys %$cloud;
+ return
+ '<div id="htmltagcloud"'.($project ? '' : ' align="center"').'>' .
+ join (', ', map {
+ $cloud->{$_}->{'ctag'}
+ } splice(@tags, 0, $count)) .
+ '</div>';
}
}
@@ -4905,13 +4962,8 @@ sub git_project_list_body {
@projects = sort_projects_list(\@projects, $order);
if ($show_ctags) {
- my %ctags;
- foreach my $p (@projects) {
- foreach my $ct (keys %{$p->{'ctags'}}) {
- $ctags{$ct} += $p->{'ctags'}->{$ct};
- }
- }
- my $cloud = git_populate_project_tagcloud(\%ctags);
+ my $ctags = git_gather_all_ctags(\@projects);
+ my $cloud = git_populate_project_tagcloud($ctags);
print git_show_project_tagcloud($cloud, 64);
}
@@ -5507,13 +5559,14 @@ sub git_summary {
my $show_ctags = gitweb_check_feature('ctags');
if ($show_ctags) {
my $ctags = git_get_project_ctags($project);
- my $cloud = git_populate_project_tagcloud($ctags);
- print "<tr id=\"metadata_ctags\"><td>Content tags:<br />";
- print "</td>\n<td>" unless %$ctags;
- print "<form action=\"$show_ctags\" method=\"post\"><input type=\"hidden\" name=\"p\" value=\"$project\" />Add: <input type=\"text\" name=\"t\" size=\"8\" /></form>";
- print "</td>\n<td>" if %$ctags;
- print git_show_project_tagcloud($cloud, 48);
- print "</td></tr>";
+ if (%$ctags) {
+ # without ability to add tags, don't show if there are none
+ my $cloud = git_populate_project_tagcloud($ctags);
+ print "<tr id=\"metadata_ctags\">" .
+ "<td>content tags</td>" .
+ "<td>".git_show_project_tagcloud($cloud, 48)."</td>" .
+ "</tr>\n";
+ }
}
print "</table>\n";
--
1.7.3
next prev parent reply other threads:[~2011-03-07 18:08 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20110301190229.11297.17767.reportbug@cassiopeia.kleinek>
2011-03-01 22:21 ` gitweb: cloud tags feature produces malformed XML for errors Jonathan Nieder
2011-03-02 0:05 ` Jakub Narebski
2011-03-02 8:24 ` Jakub Narebski
2011-03-02 8:45 ` Uwe Kleine-König
2011-03-02 1:06 ` J.H.
2011-03-02 21:18 ` Jakub Narebski
2011-03-02 21:55 ` Uwe Kleine-König
2011-03-03 0:42 ` Jakub Narebski
2011-03-03 8:19 ` Uwe Kleine-König
2011-03-07 18:00 ` Jakub Narebski [this message]
2011-03-09 14:04 ` [PATCH 2/1] gitweb: Mark matched 'ctag' / contents tag (?by_tag=foo) Jakub Narebski
2011-03-09 14:09 ` Petr Baudis
2011-06-09 7:08 ` [PATCH] gitweb: do misparse nonnumeric content tag files that contain a digit Jonathan Nieder
2011-06-09 7:11 ` Jonathan Nieder
2011-03-03 11:58 ` gitweb: cloud tags feature produces malformed XML for errors Petr Baudis
2011-03-03 13:29 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201103071900.16126.jnareb@gmail.com \
--to=jnareb@gmail.com \
--cc=admin@repo.or.cz \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=u.kleine-koenig@pengutronix.de \
--cc=warthog9@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).