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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.