{"thread":{"id":"10603","subject":"[PATCH 1/3] gitweb: Add tests for overriding gitweb config with repo config","startedAt":"2007-11-02T23:41:17Z","lastAt":"2007-11-02T23:41:20Z","messageCount":4,"participants":["Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"58056","messageId":"1194046880-29941-1-git-send-email-jnareb@gmail.com","threadId":"10603","inReplyTo":null,"subject":"[PATCH 0/3] gitweb: Improve reading of repo config","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-11-02T23:41:17Z","receivedAt":"2007-11-02T23:41:17Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This series of patches introduces single-call reading of\ngitweb-related part of repository configuration in gitweb. Instead of\ncalling git-config once for each config variable we check, read all\nvariables at once for first request of repo config variable.\n\nFirst patch adds test to check if our changes do not break gitweb too\nbadly, second one introduces mentioned above \"eager\" repo config\nreading, and third makes use of the fact that adding new configuration\nvariables to check is not that costly now.\n\nTable of contents:\n==================\n [PATCH 1/3] gitweb: Add tests for overriding gitweb config with repo config\n [PATCH 2/3] gitweb: Read repo config using 'git config -z -l'\n [PATCH 3/3] gitweb: Use config file for repository description and URLs\n\nDiffstat:\n=========\n gitweb/gitweb.perl |   82 +++++++++++++++++++++----------------------------\n 1 files changed, 33 insertions(+), 47 deletions(-)\n\n-- \nJakub Narebski, Poland\ngit version 1.5.3.5\n"},{"id":"58053","messageId":"1194046880-29941-2-git-send-email-jnareb@gmail.com","threadId":"10603","inReplyTo":"1194046880-29941-1-git-send-email-jnareb@gmail.com","subject":"[PATCH 1/3] gitweb: Add tests for overriding gitweb config with repo config","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-11-02T23:41:18Z","receivedAt":"2007-11-02T23:41:18Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Make blame view and snapshot support overridable by repository\nconfig. Test tree view with both features disabled, and with both\nfeatures enabled.\n\nTest with features enabled also tests multiple formats snapshot\nsupport (in tree view).\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nIf I remember correctly it was when creating this test that there were\nprobles with CGI::Carp::set_programname() in t9500 test. And it took\nme some time to discover where the bug was.\n\n t/t9500-gitweb-standalone-no-errors.sh |   23 +++++++++++++++++++++++\n 1 files changed, 23 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh\nindex 1bf0988..35fff3d 100755\n--- a/t/t9500-gitweb-standalone-no-errors.sh\n+++ b/t/t9500-gitweb-standalone-no-errors.sh\n@@ -557,4 +557,27 @@ test_expect_success \\\n \t'gitweb_run \"p=.git;a=tree;opt=--no-merges\"'\n test_debug 'cat gitweb.log'\n \n+# ----------------------------------------------------------------------\n+# gitweb config and repo config\n+\n+cat >>gitweb_config.perl <<EOF\n+\n+\\$feature{'blame'}{'override'} = 1;\n+\\$feature{'snapshot'}{'override'} = 1;\n+EOF\n+\n+test_expect_success \\\n+\t'config override: tree view, features disabled in repo config' \\\n+\t'git config gitweb.blame no &&\n+\t git config gitweb.snapshot none &&\n+\t gitweb_run \"p=.git;a=tree\"'\n+test_debug 'cat gitweb.log'\n+\n+test_expect_success \\\n+\t'config override: tree view, features enabled in repo config' \\\n+\t'git config gitweb.blame yes &&\n+\t git config gitweb.snapshot \"zip,tgz, tbz2\" &&\n+\t gitweb_run \"p=.git;a=tree\"'\n+test_debug 'cat gitweb.log'\n+\n test_done\n-- \n1.5.3.5\n"},{"id":"58055","messageId":"1194046880-29941-3-git-send-email-jnareb@gmail.com","threadId":"10603","inReplyTo":"1194046880-29941-1-git-send-email-jnareb@gmail.com","subject":"[PATCH 2/3] gitweb: Read repo config using 'git config -z -l'","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-11-02T23:41:19Z","receivedAt":"2007-11-02T23:41:19Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Change git_get_project_config to run git-config only once per\nrepository, without changing its signature (its calling convention).\nThis means for example that it returns 'true' or 'false' when called\nwith second argument '--bool', and not true or false value.\n\nInstead of calling 'git config [<type>] --get gitweb.<key>' once for\neach config variable, call 'git config -z -l' only once, parsing and\nsaving its output to %config variable.  This makes possible to add new\nper repository configuration without paying cost of forking once per\nvariable checked.  We can now allow repository description and\nrepository URLs to be stored in config file without badly affecting\ngitweb performance.\n\nFor now only configuration variables for 'gitweb' section are stored.\n\nMultiple values for single configuration variable are stored as\nanonymous array reference; configuration variable with no value is\nstored as undef.\n\nConverting configuration variable values to boolean or integer value\nare done in Perl.  Results differ from git-config in the fact that no\nconversion error is ever raised.  For boolean values no value, 'true'\n(any case) and 'false' (any case) are considered true, numbers are\ntrue if not zero; all other values (even invalid for bool) are\nconsidered false.  For integer values value suffix of 'k', 'm', or 'g'\nfollowing decimal number will cause the value to be multiplied by\n1024, 1048576, or 1073741824; other values are returned as-is, only\nwhitespace stripped.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nThis makes use of commit 2275d502114c71045af991697048191fed88aac4\n  \"config: Add --null/-z option for null-delimted output\"\nby Frank Lichtenheld. The --null/-z option to git-config was created\namong others with gitweb in mind, if I remember correctly.\n\nIn the future we would most probably want to move this to Git.pm, and\nuse Git.pm in gitweb.\n\n gitweb/gitweb.perl |  115 ++++++++++++++++++++++++++++++++++++++++++++++++---\n 1 files changed, 108 insertions(+), 7 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 827f977..f54455b 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1432,20 +1432,121 @@ sub git_get_type {\n \treturn $type;\n }\n \n+# repository configuration\n+our $config_file = '';\n+our %config;\n+\n+# store multiple values for single key as anonymous array reference\n+# single values stored directly in the hash, not as [ <value> ]\n+sub hash_set_multi {\n+\tmy ($hash, $key, $value) = @_;\n+\n+\tif (!exists $hash->{$key}) {\n+\t\t$hash->{$key} = $value;\n+\t} elsif (!ref $hash->{$key}) {\n+\t\t$hash->{$key} = [ $hash->{$key}, $value ];\n+\t} else {\n+\t\tpush @{$hash->{$key}}, $value;\n+\t}\n+}\n+\n+# return hash of git project configuration\n+# optionally limited to some section, e.g. 'gitweb'\n+sub git_parse_project_config {\n+\tmy $section_regexp = shift;\n+\tmy %config;\n+\n+\tlocal $/ = \"\\0\";\n+\n+\topen my $fh, \"-|\", git_cmd(), \"config\", '-z', '-l',\n+\t\tor return;\n+\n+\twhile (my $keyval = <$fh>) {\n+\t\tchomp $keyval;\n+\t\tmy ($key, $value) = split(/\\n/, $keyval, 2);\n+\n+\t\thash_set_multi(\\%config, $key, $value)\n+\t\t\tif (!defined $section_regexp || $key =~ /^(?:$section_regexp)\\./o);\n+\t}\n+\tclose $fh;\n+\n+\treturn %config;\n+}\n+\n+# convert config value to boolean, 'true' or 'false'\n+# no value, number > 0, 'true' and 'yes' values are true\n+# rest of values are treated as false (never as error)\n+sub config_to_bool {\n+\tmy $val = shift;\n+\n+\t# strip leading and trailing whitespace\n+\t$val =~ s/^\\s+//;\n+\t$val =~ s/\\s+$//;\n+\n+\treturn (!defined $val ||               # section.key\n+\t        ($val =~ /^\\d+$/ && $val) ||   # section.key = 1\n+\t        ($val =~ /^(?:true|yes)$/i));  # section.key = true\n+}\n+\n+# convert config value to simple decimal number\n+# an optional value suffix of 'k', 'm', or 'g' will cause the value\n+# to be multiplied by 1024, 1048576, or 1073741824\n+sub config_to_int {\n+\tmy $val = shift;\n+\n+\t# strip leading and trailing whitespace\n+\t$val =~ s/^\\s+//;\n+\t$val =~ s/\\s+$//;\n+\n+\tif (my ($num, $unit) = ($val =~ /^([0-9]*)([kmg])$/i)) {\n+\t\t$unit = lc($unit);\n+\t\t# unknown unit is treated as 1\n+\t\treturn $num * ($unit eq 'g' ? 1073741824 :\n+\t\t               $unit eq 'm' ?    1048576 :\n+\t\t               $unit eq 'k' ?       1024 : 1);\n+\t}\n+\treturn $val;\n+}\n+\n+# convert config value to array reference, if needed\n+sub config_to_multi {\n+\tmy $val = shift;\n+\n+\treturn ref($val) ? $val : [ $val ];\n+}\n+\n sub git_get_project_config {\n \tmy ($key, $type) = @_;\n \n+\t# key sanity check\n \treturn unless ($key);\n \t$key =~ s/^gitweb\\.//;\n \treturn if ($key =~ m/\\W/);\n \n-\tmy @x = (git_cmd(), 'config');\n-\tif (defined $type) { push @x, $type; }\n-\tpush @x, \"--get\";\n-\tpush @x, \"gitweb.$key\";\n-\tmy $val = qx(@x);\n-\tchomp $val;\n-\treturn ($val);\n+\t# type sanity check\n+\tif (defined $type) {\n+\t\t$type =~ s/^--//;\n+\t\t$type = undef\n+\t\t\tunless ($type eq 'bool' || $type eq 'int');\n+\t}\n+\n+\t# get config\n+\tif (!defined $config_file ||\n+\t    $config_file ne \"$git_dir/config\") {\n+\t\t%config = git_parse_project_config('gitweb');\n+\t\t$config_file = \"$git_dir/config\";\n+\t}\n+\n+\t# ensure given type\n+\tif (!defined $type) {\n+\t\treturn $config{\"gitweb.$key\"};\n+\t} elsif ($type eq 'bool') {\n+\t\t# backward compatibility: 'git config --bool' returns true/false\n+\t\treturn config_to_bool($config{\"gitweb.$key\"}) ? 'true' : 'false';\n+\t} elsif ($type eq 'int') {\n+\t\treturn config_to_int($config{\"gitweb.$key\"});\n+\t}\n+\treturn $config{\"gitweb.$key\"};\n }\n \n # get hash of given path at given ref\n-- \n1.5.3.5\n"},{"id":"58054","messageId":"1194046880-29941-4-git-send-email-jnareb@gmail.com","threadId":"10603","inReplyTo":"1194046880-29941-1-git-send-email-jnareb@gmail.com","subject":"[PATCH 3/3] gitweb: Use config file for repository description and URLs","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-11-02T23:41:20Z","receivedAt":"2007-11-02T23:41:20Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Allow to use configuration variable gitweb.description for repository\ndescription if there is no $GIT_DIR/description file, and multivalued\nconfiguration variable gitweb.url for URLs of a project (to clone or\nfetch from) if there is no $GIT_DIR/cloneurl file.\n\nWhile repository description is shown in the projects list page, so it\nis better to use file and not config variable for performance, it is I\nthink better to use gitweb.url for URLs (as it is shown only on\nproject summary page).\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl                     |   10 ++++++++--\n 1 files changed, 8 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex f54455b..7cac629 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1606,7 +1606,9 @@ sub git_get_path_by_hash {\n sub git_get_project_description {\n \tmy $path = shift;\n \n-\topen my $fd, \"$projectroot/$path/description\" or return undef;\n+\t$git_dir = \"$projectroot/$path\";\n+\topen my $fd, \"$projectroot/$path/description\"\n+\t\tor return git_get_project_config('description');\n \tmy $descr = <$fd>;\n \tclose $fd;\n \tif (defined $descr) {\n@@ -1618,7 +1620,11 @@ sub git_get_project_description {\n sub git_get_project_url_list {\n \tmy $path = shift;\n \n-\topen my $fd, \"$projectroot/$path/cloneurl\" or return;\n+\t$git_dir = \"$projectroot/$path\";\n+\topen my $fd, \"$projectroot/$path/cloneurl\"\n+\t\tor return wantarray ?\n+\t\t@{ config_to_multi(git_get_project_config('url')) } :\n+\t\t   config_to_multi(git_get_project_config('url'));\n \tmy @git_project_url_list = map { chomp; $_ } <$fd>;\n \tclose $fd;\n \n-- \n1.5.3.5\n"}]}