gitweb: Add support for enabling 'write' feature
[git/gsoc2010-gitweb.git] / gitweb / lib / Gitweb / Config.pm
blobf4fa9df45313dc68e3537f2216b3f9689ff3b949
1 #!/usr/bin/perl
3 # Gitweb::Config -- gitweb configuration package
5 # This program is licensed under the GPLv2
7 package Gitweb::Config;
9 use strict;
10 use warnings;
11 use Exporter qw(import);
13 our @EXPORT = qw(evaluate_gitweb_config gitweb_check_feature gitweb_get_feature configure_gitweb_features
14 filter_snapshot_fmts %known_snapshot_formats $version $projectroot $project_maxdepth
15 $projects_list @git_base_url_list $export_ok $strict_export $home_link_str $site_name
16 $site_header $site_footer $home_text @stylesheets $stylesheet $logo $favicon $javascript
17 $GITWEB_CONFIG $GITWEB_CONFIG_SYSTEM $logo_url $logo_label $export_auth_hook
18 $projects_list_description_width $default_projects_order $default_blob_plain_mimetype
19 $default_text_plain_charset $fallback_encoding @diff_opts $prevent_xss $maxload
20 $git_avatar %avatar_size %feature @snapshot_fmts $mimetypes_file $git_write);
22 use Gitweb::Git qw($git_dir);
24 # The following variables are affected by build-time configuration
25 # and hence their initialisation is put in gitweb.perl script
27 our $version;
29 # absolute fs-path which will be prepended to the project path
30 #our $projectroot = "/pub/scm";
31 our $projectroot;
32 # fs traversing limit for getting project list
33 # the number is relative to the projectroot
34 our $project_maxdepth;
35 # source of projects list
36 our $projects_list;
37 # list of git base URLs used for URL to where fetch project from,
38 # i.e. full URL is "$git_base_url/$project"
39 our @git_base_url_list;
41 # show repository only if this file exists
42 # (only effective if this variable evaluates to true)
43 our $export_ok;
44 # only allow viewing of repositories also shown on the overview page
45 our $strict_export;
47 # string of the home link on top of all pages
48 our $home_link_str;
49 # name of your site or organization to appear in page titles
50 # replace this with something more descriptive for clearer bookmarks
51 our $site_name;
52 # filename of html text to include at top of each page
53 our $site_header;
54 # filename of html text to include at bottom of each page
55 our $site_footer;
56 # html text to include at home page
57 our $home_text;
59 # URI of stylesheets
60 our @stylesheets;
61 # URI of a single stylesheet, which can be overridden in GITWEB_CONFIG.
62 our $stylesheet;
63 # URI of GIT logo (72x27 size)
64 our $logo;
65 # URI of GIT favicon, assumed to be image/png type
66 our $favicon;
67 # URI of gitweb.js (JavaScript code for gitweb)
68 our $javascript;
70 # gitweb config
71 our ($GITWEB_CONFIG, $GITWEB_CONFIG_SYSTEM);
73 # URI and label (title) of GIT logo link
74 #our $logo_url = "http://www.kernel.org/pub/software/scm/git/docs/";
75 #our $logo_label = "git documentation";
76 our $logo_url = "http://git-scm.com/";
77 our $logo_label = "git homepage";
79 # the width (in characters) of the projects list "Description" column
80 our $projects_list_description_width = 25;
82 # default order of projects list
83 # valid values are none, project, descr, owner, and age
84 our $default_projects_order = "project";
86 # show repository only if this subroutine returns true
87 # when given the path to the project, for example:
88 # sub { return -e "$_[0]/git-daemon-export-ok"; }
89 our $export_auth_hook = undef;
91 # default blob_plain mimetype and default charset for text/plain blob
92 our $default_blob_plain_mimetype = 'text/plain';
93 our $default_text_plain_charset = undef;
95 # file to use for guessing MIME types before trying /etc/mime.types
96 # (relative to the current git repository)
97 our $mimetypes_file = undef;
99 # assume this charset if line contains non-UTF-8 characters;
100 # it should be valid encoding (see Encoding::Supported(3pm) for list),
101 # for which encoding all byte sequences are valid, for example
102 # 'iso-8859-1' aka 'latin1' (it is decoded without checking, so it
103 # could be even 'utf-8' for the old behavior)
104 our $fallback_encoding = 'latin1';
106 # rename detection options for git-diff and git-diff-tree
107 # - default is '-M', with the cost proportional to
108 # (number of removed files) * (number of new files).
109 # - more costly is '-C' (which implies '-M'), with the cost proportional to
110 # (number of changed files + number of removed files) * (number of new files)
111 # - even more costly is '-C', '--find-copies-harder' with cost
112 # (number of files in the original tree) * (number of new files)
113 # - one might want to include '-B' option, e.g. '-B', '-M'
114 our @diff_opts = ('-M'); # taken from git_commit
116 # Disables features that would allow repository owners to inject script into
117 # the gitweb domain.
118 our $prevent_xss = 0;
120 # information about snapshot formats that gitweb is capable of serving
121 our %known_snapshot_formats = (
122 # name => {
123 # 'display' => display name,
124 # 'type' => mime type,
125 # 'suffix' => filename suffix,
126 # 'format' => --format for git-archive,
127 # 'compressor' => [compressor command and arguments]
128 # (array reference, optional)
129 # 'disabled' => boolean (optional)}
131 'tgz' => {
132 'display' => 'tar.gz',
133 'type' => 'application/x-gzip',
134 'suffix' => '.tar.gz',
135 'format' => 'tar',
136 'compressor' => ['gzip']},
138 'tbz2' => {
139 'display' => 'tar.bz2',
140 'type' => 'application/x-bzip2',
141 'suffix' => '.tar.bz2',
142 'format' => 'tar',
143 'compressor' => ['bzip2']},
145 'txz' => {
146 'display' => 'tar.xz',
147 'type' => 'application/x-xz',
148 'suffix' => '.tar.xz',
149 'format' => 'tar',
150 'compressor' => ['xz'],
151 'disabled' => 1},
153 'zip' => {
154 'display' => 'zip',
155 'type' => 'application/x-zip',
156 'suffix' => '.zip',
157 'format' => 'zip'},
160 # Aliases so we understand old gitweb.snapshot values in repository
161 # configuration.
162 our %known_snapshot_format_aliases = (
163 'gzip' => 'tgz',
164 'bzip2' => 'tbz2',
165 'xz' => 'txz',
167 # backward compatibility: legacy gitweb config support
168 'x-gzip' => undef, 'gz' => undef,
169 'x-bzip2' => undef, 'bz2' => undef,
170 'x-zip' => undef, '' => undef,
173 # Pixel sizes for icons and avatars. If the default font sizes or lineheights
174 # are changed, it may be appropriate to change these values too via
175 # $GITWEB_CONFIG.
176 our %avatar_size = (
177 'default' => 16,
178 'double' => 32
181 # Used to set the maximum load that we will still respond to gitweb queries.
182 # If server load exceed this value then return "503 server busy" error.
183 # If gitweb cannot determined server load, it is taken to be 0.
184 # Leave it undefined (or set to 'undef') to turn off load checking.
185 our $maxload = 300;
187 # You define site-wide feature defaults here; override them with
188 # $GITWEB_CONFIG as necessary.
189 our %feature = (
190 # feature => {
191 # 'sub' => feature-sub (subroutine),
192 # 'override' => allow-override (boolean),
193 # 'default' => [ default options...] (array reference)}
195 # if feature is overridable (it means that allow-override has true value),
196 # then feature-sub will be called with default options as parameters;
197 # return value of feature-sub indicates if to enable specified feature
199 # if there is no 'sub' key (no feature-sub), then feature cannot be
200 # overriden
202 # use gitweb_get_feature(<feature>) to retrieve the <feature> value
203 # (an array) or gitweb_check_feature(<feature>) to check if <feature>
204 # is enabled
206 # Enable the 'write' functionalities for gitweb. While outputting HTML
207 # it checks for gitweb_check_feature('write') and if it's enabled,
208 # proper links will appear along with the HTML divs.
210 # To enable system wide have in $GITWEB_CONFIG
211 # $feature{'write'}{'default'} = [1];
212 # Project specific override is not supported.
213 'write' => {
214 'override' => 0,
215 'default' => [0]},
217 # Enable the 'blame' blob view, showing the last commit that modified
218 # each line in the file. This can be very CPU-intensive.
220 # To enable system wide have in $GITWEB_CONFIG
221 # $feature{'blame'}{'default'} = [1];
222 # To have project specific config enable override in $GITWEB_CONFIG
223 # $feature{'blame'}{'override'} = 1;
224 # and in project config gitweb.blame = 0|1;
225 'blame' => {
226 'sub' => sub { feature_bool('blame', @_) },
227 'override' => 0,
228 'default' => [0]},
230 # Enable the 'snapshot' link, providing a compressed archive of any
231 # tree. This can potentially generate high traffic if you have large
232 # project.
234 # Value is a list of formats defined in %known_snapshot_formats that
235 # you wish to offer.
236 # To disable system wide have in $GITWEB_CONFIG
237 # $feature{'snapshot'}{'default'} = [];
238 # To have project specific config enable override in $GITWEB_CONFIG
239 # $feature{'snapshot'}{'override'} = 1;
240 # and in project config, a comma-separated list of formats or "none"
241 # to disable. Example: gitweb.snapshot = tbz2,zip;
242 'snapshot' => {
243 'sub' => \&feature_snapshot,
244 'override' => 0,
245 'default' => ['tgz']},
247 # Enable text search, which will list the commits which match author,
248 # committer or commit text to a given string. Enabled by default.
249 # Project specific override is not supported.
250 'search' => {
251 'override' => 0,
252 'default' => [1]},
254 # Enable grep search, which will list the files in currently selected
255 # tree containing the given string. Enabled by default. This can be
256 # potentially CPU-intensive, of course.
258 # To enable system wide have in $GITWEB_CONFIG
259 # $feature{'grep'}{'default'} = [1];
260 # To have project specific config enable override in $GITWEB_CONFIG
261 # $feature{'grep'}{'override'} = 1;
262 # and in project config gitweb.grep = 0|1;
263 'grep' => {
264 'sub' => sub { feature_bool('grep', @_) },
265 'override' => 0,
266 'default' => [1]},
268 # Enable the pickaxe search, which will list the commits that modified
269 # a given string in a file. This can be practical and quite faster
270 # alternative to 'blame', but still potentially CPU-intensive.
272 # To enable system wide have in $GITWEB_CONFIG
273 # $feature{'pickaxe'}{'default'} = [1];
274 # To have project specific config enable override in $GITWEB_CONFIG
275 # $feature{'pickaxe'}{'override'} = 1;
276 # and in project config gitweb.pickaxe = 0|1;
277 'pickaxe' => {
278 'sub' => sub { feature_bool('pickaxe', @_) },
279 'override' => 0,
280 'default' => [1]},
282 # Enable showing size of blobs in a 'tree' view, in a separate
283 # column, similar to what 'ls -l' does. This cost a bit of IO.
285 # To disable system wide have in $GITWEB_CONFIG
286 # $feature{'show-sizes'}{'default'} = [0];
287 # To have project specific config enable override in $GITWEB_CONFIG
288 # $feature{'show-sizes'}{'override'} = 1;
289 # and in project config gitweb.showsizes = 0|1;
290 'show-sizes' => {
291 'sub' => sub { feature_bool('showsizes', @_) },
292 'override' => 0,
293 'default' => [1]},
295 # Make gitweb use an alternative format of the URLs which can be
296 # more readable and natural-looking: project name is embedded
297 # directly in the path and the query string contains other
298 # auxiliary information. All gitweb installations recognize
299 # URL in either format; this configures in which formats gitweb
300 # generates links.
302 # To enable system wide have in $GITWEB_CONFIG
303 # $feature{'pathinfo'}{'default'} = [1];
304 # Project specific override is not supported.
306 # Note that you will need to change the default location of CSS,
307 # favicon, logo and possibly other files to an absolute URL. Also,
308 # if gitweb.cgi serves as your indexfile, you will need to force
309 # $my_uri to contain the script name in your $GITWEB_CONFIG.
310 'pathinfo' => {
311 'override' => 0,
312 'default' => [0]},
314 # Make gitweb consider projects in project root subdirectories
315 # to be forks of existing projects. Given project $projname.git,
316 # projects matching $projname/*.git will not be shown in the main
317 # projects list, instead a '+' mark will be added to $projname
318 # there and a 'forks' view will be enabled for the project, listing
319 # all the forks. If project list is taken from a file, forks have
320 # to be listed after the main project.
322 # To enable system wide have in $GITWEB_CONFIG
323 # $feature{'forks'}{'default'} = [1];
324 # Project specific override is not supported.
325 'forks' => {
326 'override' => 0,
327 'default' => [0]},
329 # Insert custom links to the action bar of all project pages.
330 # This enables you mainly to link to third-party scripts integrating
331 # into gitweb; e.g. git-browser for graphical history representation
332 # or custom web-based repository administration interface.
334 # The 'default' value consists of a list of triplets in the form
335 # (label, link, position) where position is the label after which
336 # to insert the link and link is a format string where %n expands
337 # to the project name, %f to the project path within the filesystem,
338 # %h to the current hash (h gitweb parameter) and %b to the current
339 # hash base (hb gitweb parameter); %% expands to %.
341 # To enable system wide have in $GITWEB_CONFIG e.g.
342 # $feature{'actions'}{'default'} = [('graphiclog',
343 # '/git-browser/by-commit.html?r=%n', 'summary')];
344 # Project specific override is not supported.
345 'actions' => {
346 'override' => 0,
347 'default' => []},
349 # Allow gitweb scan project content tags described in ctags/
350 # of project repository, and display the popular Web 2.0-ish
351 # "tag cloud" near the project list. Note that this is something
352 # COMPLETELY different from the normal Git tags.
354 # gitweb by itself can show existing tags, but it does not handle
355 # tagging itself; you need an external application for that.
356 # For an example script, check Girocco's cgi/tagproj.cgi.
357 # You may want to install the HTML::TagCloud Perl module to get
358 # a pretty tag cloud instead of just a list of tags.
360 # To enable system wide have in $GITWEB_CONFIG
361 # $feature{'ctags'}{'default'} = ['path_to_tag_script'];
362 # Project specific override is not supported.
363 'ctags' => {
364 'override' => 0,
365 'default' => [0]},
367 # The maximum number of patches in a patchset generated in patch
368 # view. Set this to 0 or undef to disable patch view, or to a
369 # negative number to remove any limit.
371 # To disable system wide have in $GITWEB_CONFIG
372 # $feature{'patches'}{'default'} = [0];
373 # To have project specific config enable override in $GITWEB_CONFIG
374 # $feature{'patches'}{'override'} = 1;
375 # and in project config gitweb.patches = 0|n;
376 # where n is the maximum number of patches allowed in a patchset.
377 'patches' => {
378 'sub' => \&feature_patches,
379 'override' => 0,
380 'default' => [16]},
382 # Avatar support. When this feature is enabled, views such as
383 # shortlog or commit will display an avatar associated with
384 # the email of the committer(s) and/or author(s).
386 # Currently available providers are gravatar and picon.
387 # If an unknown provider is specified, the feature is disabled.
389 # Gravatar depends on Digest::MD5.
390 # Picon currently relies on the indiana.edu database.
392 # To enable system wide have in $GITWEB_CONFIG
393 # $feature{'avatar'}{'default'} = ['<provider>'];
394 # where <provider> is either gravatar or picon.
395 # To have project specific config enable override in $GITWEB_CONFIG
396 # $feature{'avatar'}{'override'} = 1;
397 # and in project config gitweb.avatar = <provider>;
398 'avatar' => {
399 'sub' => \&feature_avatar,
400 'override' => 0,
401 'default' => ['']},
403 # Enable displaying how much time and how many git commands
404 # it took to generate and display page. Disabled by default.
405 # Project specific override is not supported.
406 'timed' => {
407 'override' => 0,
408 'default' => [0]},
410 # Enable turning some links into links to actions which require
411 # JavaScript to run (like 'blame_incremental'). Not enabled by
412 # default. Project specific override is currently not supported.
413 'javascript-actions' => {
414 'override' => 0,
415 'default' => [0]},
417 # Syntax highlighting support. This is based on Daniel Svensson's
418 # and Sham Chukoury's work in gitweb-xmms2.git.
419 # It requires the 'highlight' program present in $PATH,
420 # and therefore is disabled by default.
422 # To enable system wide have in $GITWEB_CONFIG
423 # $feature{'highlight'}{'default'} = [1];
425 'highlight' => {
426 'sub' => sub { feature_bool('highlight', @_) },
427 'override' => 0,
428 'default' => [0]},
431 sub evaluate_gitweb_config {
432 # die if there are errors parsing config file
433 if (-e $GITWEB_CONFIG) {
434 do $GITWEB_CONFIG;
435 die $@ if $@;
436 } elsif (-e $GITWEB_CONFIG_SYSTEM) {
437 do $GITWEB_CONFIG_SYSTEM;
438 die $@ if $@;
443 sub gitweb_get_feature {
444 my ($name) = @_;
445 return unless exists $feature{$name};
446 my ($sub, $override, @defaults) = (
447 $feature{$name}{'sub'},
448 $feature{$name}{'override'},
449 @{$feature{$name}{'default'}});
450 # project specific override is possible only if we have project
451 if (!$override || !defined $git_dir) {
452 return @defaults;
454 if (!defined $sub) {
455 warn "feature $name is not overridable";
456 return @defaults;
458 return $sub->(@defaults);
461 # A wrapper to check if a given feature is enabled.
462 # With this, you can say
464 # my $bool_feat = gitweb_check_feature('bool_feat');
465 # gitweb_check_feature('bool_feat') or somecode;
467 # instead of
469 # my ($bool_feat) = gitweb_get_feature('bool_feat');
470 # (gitweb_get_feature('bool_feat'))[0] or somecode;
472 sub gitweb_check_feature {
473 return (gitweb_get_feature(@_))[0];
476 # process alternate names for backward compatibility
477 # filter out unsupported (unknown) snapshot formats
478 sub filter_snapshot_fmts {
479 my @fmts = @_;
481 @fmts = map {
482 exists $known_snapshot_format_aliases{$_} ?
483 $known_snapshot_format_aliases{$_} : $_} @fmts;
484 @fmts = grep {
485 exists $known_snapshot_formats{$_} &&
486 !$known_snapshot_formats{$_}{'disabled'}} @fmts;
489 our (@snapshot_fmts, $git_avatar, $git_write);
490 sub configure_gitweb_features {
491 # list of supported snapshot formats
492 our @snapshot_fmts = gitweb_get_feature('snapshot');
493 @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);
495 # A variable flag to check 'write' feature
496 our $git_write = gitweb_check_feature('write');
498 # check that the avatar feature is set to a known provider name,
499 # and for each provider check if the dependencies are satisfied.
500 # if the provider name is invalid or the dependencies are not met,
501 # reset $git_avatar to the empty string.
502 our ($git_avatar) = gitweb_get_feature('avatar');
503 if ($git_avatar eq 'gravatar') {
504 $git_avatar = '' unless (eval { require Digest::MD5; 1; });
505 } elsif ($git_avatar eq 'picon') {
506 # no dependencies
507 } else {
508 $git_avatar = '';