Support specifying the repository owner indirectly.
[gitosis/httpauth.git] / gitosis / gitweb.py
blobccfcd9ef3034036c4d480c8bf774701a06ec843e
1 """
2 Generate ``gitweb`` project list based on ``gitosis.conf``.
4 To plug this into ``gitweb``, you have two choices.
6 - The global way, edit ``/etc/gitweb.conf`` to say::
8 $projects_list = "/path/to/your/projects.list";
10 Note that there can be only one such use of gitweb.
12 - The local way, create a new config file::
14 do "/etc/gitweb.conf" if -e "/etc/gitweb.conf";
15 $projects_list = "/path/to/your/projects.list";
16 # see ``repositories`` in the ``gitosis`` section
17 # of ``~/.gitosis.conf``; usually ``~/repositories``
18 # but you need to expand the tilde here
19 $projectroot = "/path/to/your/repositories";
21 Then in your web server, set environment variable ``GITWEB_CONFIG``
22 to point to this file.
24 This way allows you have multiple separate uses of ``gitweb``, and
25 isolates the changes a bit more nicely. Recommended.
26 """
28 import os, urllib, logging
30 from ConfigParser import NoSectionError, NoOptionError
32 from gitosis import util
34 def _escape_filename(s):
35 s = s.replace('\\', '\\\\')
36 s = s.replace('$', '\\$')
37 s = s.replace('"', '\\"')
38 return s
40 def generate_project_list_fp(config, fp):
41 """
42 Generate projects list for ``gitweb``.
44 :param config: configuration to read projects from
45 :type config: RawConfigParser
47 :param fp: writable for ``projects.list``
48 :type fp: (file-like, anything with ``.write(data)``)
49 """
50 log = logging.getLogger('gitosis.gitweb.generate_projects_list')
52 repositories = util.getRepositoryDir(config)
54 try:
55 global_enable = config.getboolean('gitosis', 'gitweb')
56 except (NoSectionError, NoOptionError):
57 global_enable = False
59 for section in config.sections():
60 l = section.split(None, 1)
61 type_ = l.pop(0)
62 if type_ != 'repo':
63 continue
64 if not l:
65 continue
67 try:
68 enable = config.getboolean(section, 'gitweb')
69 except (NoSectionError, NoOptionError):
70 enable = global_enable
72 if not enable:
73 continue
75 name, = l
77 if not os.path.exists(os.path.join(repositories, name)):
78 namedotgit = '%s.git' % name
79 if os.path.exists(os.path.join(repositories, namedotgit)):
80 name = namedotgit
81 else:
82 log.warning(
83 'Cannot find %(name)r in %(repositories)r'
84 % dict(name=name, repositories=repositories))
86 response = [name]
87 try:
88 owner = config.get(section, 'owner')
89 except (NoSectionError, NoOptionError):
90 pass
91 else:
92 try:
93 username = config.get('user %s' % owner, 'name')
94 except (NoSectionError, NoOptionError):
95 pass
96 else:
97 response.append(username)
98 response.append(owner)
100 line = ' '.join([urllib.quote_plus(s) for s in response])
101 print >>fp, line
103 def generate_project_list(config, path):
105 Generate projects list for ``gitweb``.
107 :param config: configuration to read projects from
108 :type config: RawConfigParser
110 :param path: path to write projects list to
111 :type path: str
113 tmp = '%s.%d.tmp' % (path, os.getpid())
115 f = file(tmp, 'w')
116 try:
117 generate_project_list_fp(config=config, fp=f)
118 finally:
119 f.close()
121 os.rename(tmp, path)
124 def set_descriptions(config):
126 Set descriptions for gitweb use.
128 log = logging.getLogger('gitosis.gitweb.set_descriptions')
130 repositories = util.getRepositoryDir(config)
132 for section in config.sections():
133 l = section.split(None, 1)
134 type_ = l.pop(0)
135 if type_ != 'repo':
136 continue
137 if not l:
138 continue
140 try:
141 description = config.get(section, 'description')
142 except (NoSectionError, NoOptionError):
143 continue
145 if not description:
146 continue
148 name, = l
150 if not os.path.exists(os.path.join(repositories, name)):
151 namedotgit = '%s.git' % name
152 if os.path.exists(os.path.join(repositories, namedotgit)):
153 name = namedotgit
154 else:
155 log.warning(
156 'Cannot find %(name)r in %(repositories)r'
157 % dict(name=name, repositories=repositories))
158 continue
160 path = os.path.join(
161 repositories,
162 name,
163 'description',
165 tmp = '%s.%d.tmp' % (path, os.getpid())
166 f = file(tmp, 'w')
167 try:
168 print >>f, description
169 finally:
170 f.close()
171 os.rename(tmp, path)