##// END OF EJS Templates
Enable demandimport only in scripts, not in importable modules (issue605)...
Thomas Arendsen Hein -
r5197:55860a45 default
parent child Browse files
Show More
@@ -1,48 +1,51 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # Copyright 2005-2007 by Intevation GmbH <intevation@intevation.de>
4 4 # Author(s):
5 5 # Thomas Arendsen Hein <thomas@intevation.de>
6 6 #
7 7 # This software may be used and distributed according to the terms
8 8 # of the GNU General Public License, incorporated herein by reference.
9 9
10 10 """
11 11 hg-ssh - a wrapper for ssh access to a limited set of mercurial repos
12 12
13 13 To be used in ~/.ssh/authorized_keys with the "command" option, see sshd(8):
14 14 command="hg-ssh path/to/repo1 /path/to/repo2 ~/repo3 ~user/repo4" ssh-dss ...
15 15 (probably together with these other useful options:
16 16 no-port-forwarding,no-X11-forwarding,no-agent-forwarding)
17 17
18 18 This allows pull/push over ssh to to the repositories given as arguments.
19 19
20 20 If all your repositories are subdirectories of a common directory, you can
21 21 allow shorter paths with:
22 22 command="cd path/to/my/repositories && hg-ssh repo1 subdir/repo2"
23 23
24 24 You can use pattern matching of your normal shell, e.g.:
25 25 command="cd repos && hg-ssh user/thomas/* projects/{mercurial,foo}"
26 26 """
27 27
28 # enable importing on demand to reduce startup time
29 from mercurial import demandimport; demandimport.enable()
30
28 31 from mercurial import dispatch
29 32
30 33 import sys, os
31 34
32 35 cwd = os.getcwd()
33 36 allowed_paths = [os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
34 37 for path in sys.argv[1:]]
35 38 orig_cmd = os.getenv('SSH_ORIGINAL_COMMAND', '?')
36 39
37 40 if orig_cmd.startswith('hg -R ') and orig_cmd.endswith(' serve --stdio'):
38 41 path = orig_cmd[6:-14]
39 42 repo = os.path.normpath(os.path.join(cwd, os.path.expanduser(path)))
40 43 if repo in allowed_paths:
41 44 dispatch.dispatch(['-R', repo, 'serve', '--stdio'])
42 45 else:
43 46 sys.stderr.write("Illegal repository %r\n" % repo)
44 47 sys.exit(-1)
45 48 else:
46 49 sys.stderr.write("Illegal command %r\n" % orig_cmd)
47 50 sys.exit(-1)
48 51
@@ -1,47 +1,50 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # An example CGI script to export multiple hgweb repos, edit as necessary
4 4
5 # enable demandloading to reduce startup time
6 from mercurial import demandimport; demandimport.enable()
7
5 8 # send python tracebacks to the browser if an error occurs:
6 9 import cgitb
7 10 cgitb.enable()
8 11
9 12 # adjust python path if not a system-wide install:
10 13 #import sys
11 14 #sys.path.insert(0, "/path/to/python/lib")
12 15
13 16 # If you'd like to serve pages with UTF-8 instead of your default
14 17 # locale charset, you can do so by uncommenting the following lines.
15 18 # Note that this will cause your .hgrc files to be interpreted in
16 19 # UTF-8 and all your repo files to be displayed using UTF-8.
17 20 #
18 21 #import os
19 22 #os.environ["HGENCODING"] = "UTF-8"
20 23
21 24 from mercurial.hgweb.hgwebdir_mod import hgwebdir
22 25 from mercurial.hgweb.request import wsgiapplication
23 26 from flup.server.fcgi import WSGIServer
24 27
25 28 # The config file looks like this. You can have paths to individual
26 29 # repos, collections of repos in a directory tree, or both.
27 30 #
28 31 # [paths]
29 32 # virtual/path = /real/path
30 33 # virtual/path = /real/path
31 34 #
32 35 # [collections]
33 36 # /prefix/to/strip/off = /root/of/tree/full/of/repos
34 37 #
35 38 # collections example: say directory tree /foo contains repos /foo/bar,
36 39 # /foo/quux/baz. Give this config section:
37 40 # [collections]
38 41 # /foo = /foo
39 42 # Then repos will list as bar and quux/baz.
40 43 #
41 44 # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
42 45 # or use a dictionary with entries like 'virtual/path': '/real/path'
43 46
44 47 def make_web_app():
45 48 return hgwebdir("hgweb.config")
46 49
47 50 WSGIServer(wsgiapplication(make_web_app)).run()
@@ -1,11 +1,14 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # mercurial - scalable distributed SCM
4 4 #
5 5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
6 6 #
7 7 # This software may be used and distributed according to the terms
8 8 # of the GNU General Public License, incorporated herein by reference.
9 9
10 # enable importing on demand to reduce startup time
11 from mercurial import demandimport; demandimport.enable()
12
10 13 import mercurial.dispatch
11 14 mercurial.dispatch.run()
@@ -1,28 +1,31 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # An example CGI script to use hgweb, edit as necessary
4 4
5 # enable importing on demand to reduce startup time
6 from mercurial import demandimport; demandimport.enable()
7
5 8 # send python tracebacks to the browser if an error occurs:
6 9 import cgitb
7 10 cgitb.enable()
8 11
9 12 # adjust python path if not a system-wide install:
10 13 #import sys
11 14 #sys.path.insert(0, "/path/to/python/lib")
12 15
13 16 # If you'd like to serve pages with UTF-8 instead of your default
14 17 # locale charset, you can do so by uncommenting the following lines.
15 18 # Note that this will cause your .hgrc files to be interpreted in
16 19 # UTF-8 and all your repo files to be displayed using UTF-8.
17 20 #
18 21 #import os
19 22 #os.environ["HGENCODING"] = "UTF-8"
20 23
21 24 from mercurial.hgweb.hgweb_mod import hgweb
22 25 from mercurial.hgweb.request import wsgiapplication
23 26 import mercurial.hgweb.wsgicgi as wsgicgi
24 27
25 28 def make_web_app():
26 29 return hgweb("/path/to/repo", "repository name")
27 30
28 31 wsgicgi.launch(wsgiapplication(make_web_app))
@@ -1,47 +1,50 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # An example CGI script to export multiple hgweb repos, edit as necessary
4 4
5 # enable importing on demand to reduce startup time
6 from mercurial import demandimport; demandimport.enable()
7
5 8 # send python tracebacks to the browser if an error occurs:
6 9 import cgitb
7 10 cgitb.enable()
8 11
9 12 # adjust python path if not a system-wide install:
10 13 #import sys
11 14 #sys.path.insert(0, "/path/to/python/lib")
12 15
13 16 # If you'd like to serve pages with UTF-8 instead of your default
14 17 # locale charset, you can do so by uncommenting the following lines.
15 18 # Note that this will cause your .hgrc files to be interpreted in
16 19 # UTF-8 and all your repo files to be displayed using UTF-8.
17 20 #
18 21 #import os
19 22 #os.environ["HGENCODING"] = "UTF-8"
20 23
21 24 from mercurial.hgweb.hgwebdir_mod import hgwebdir
22 25 from mercurial.hgweb.request import wsgiapplication
23 26 import mercurial.hgweb.wsgicgi as wsgicgi
24 27
25 28 # The config file looks like this. You can have paths to individual
26 29 # repos, collections of repos in a directory tree, or both.
27 30 #
28 31 # [paths]
29 32 # virtual/path = /real/path
30 33 # virtual/path = /real/path
31 34 #
32 35 # [collections]
33 36 # /prefix/to/strip/off = /root/of/tree/full/of/repos
34 37 #
35 38 # collections example: say directory tree /foo contains repos /foo/bar,
36 39 # /foo/quux/baz. Give this config section:
37 40 # [collections]
38 41 # /foo = /foo
39 42 # Then repos will list as bar and quux/baz.
40 43 #
41 44 # Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
42 45 # or use a dictionary with entries like 'virtual/path': '/real/path'
43 46
44 47 def make_web_app():
45 48 return hgwebdir("hgweb.config")
46 49
47 50 wsgicgi.launch(wsgiapplication(make_web_app))
@@ -1,259 +1,258 b''
1 1 # hgweb/hgwebdir_mod.py - Web interface for a directory of repositories.
2 2 #
3 3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 4 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
5 5 #
6 6 # This software may be used and distributed according to the terms
7 7 # of the GNU General Public License, incorporated herein by reference.
8 8
9 from mercurial import demandimport; demandimport.enable()
10 9 import os, mimetools, cStringIO
11 10 from mercurial.i18n import gettext as _
12 11 from mercurial import ui, hg, util, templater
13 12 from common import get_mtime, staticfile, style_map, paritygen
14 13 from hgweb_mod import hgweb
15 14
16 15 # This is a stopgap
17 16 class hgwebdir(object):
18 17 def __init__(self, config, parentui=None):
19 18 def cleannames(items):
20 19 return [(util.pconvert(name.strip(os.sep)), path)
21 20 for name, path in items]
22 21
23 22 self.parentui = parentui
24 23 self.motd = None
25 24 self.style = None
26 25 self.stripecount = None
27 26 self.repos_sorted = ('name', False)
28 27 if isinstance(config, (list, tuple)):
29 28 self.repos = cleannames(config)
30 29 self.repos_sorted = ('', False)
31 30 elif isinstance(config, dict):
32 31 self.repos = cleannames(config.items())
33 32 self.repos.sort()
34 33 else:
35 34 if isinstance(config, util.configparser):
36 35 cp = config
37 36 else:
38 37 cp = util.configparser()
39 38 cp.read(config)
40 39 self.repos = []
41 40 if cp.has_section('web'):
42 41 if cp.has_option('web', 'motd'):
43 42 self.motd = cp.get('web', 'motd')
44 43 if cp.has_option('web', 'style'):
45 44 self.style = cp.get('web', 'style')
46 45 if cp.has_option('web', 'stripes'):
47 46 self.stripecount = int(cp.get('web', 'stripes'))
48 47 if cp.has_section('paths'):
49 48 self.repos.extend(cleannames(cp.items('paths')))
50 49 if cp.has_section('collections'):
51 50 for prefix, root in cp.items('collections'):
52 51 for path in util.walkrepos(root):
53 52 repo = os.path.normpath(path)
54 53 name = repo
55 54 if name.startswith(prefix):
56 55 name = name[len(prefix):]
57 56 self.repos.append((name.lstrip(os.sep), repo))
58 57 self.repos.sort()
59 58
60 59 def run(self):
61 60 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
62 61 raise RuntimeError("This function is only intended to be called while running as a CGI script.")
63 62 import mercurial.hgweb.wsgicgi as wsgicgi
64 63 from request import wsgiapplication
65 64 def make_web_app():
66 65 return self
67 66 wsgicgi.launch(wsgiapplication(make_web_app))
68 67
69 68 def run_wsgi(self, req):
70 69 def header(**map):
71 70 header_file = cStringIO.StringIO(
72 71 ''.join(tmpl("header", encoding=util._encoding, **map)))
73 72 msg = mimetools.Message(header_file, 0)
74 73 req.header(msg.items())
75 74 yield header_file.read()
76 75
77 76 def footer(**map):
78 77 yield tmpl("footer", **map)
79 78
80 79 def motd(**map):
81 80 if self.motd is not None:
82 81 yield self.motd
83 82 else:
84 83 yield config('web', 'motd', '')
85 84
86 85 parentui = self.parentui or ui.ui(report_untrusted=False)
87 86
88 87 def config(section, name, default=None, untrusted=True):
89 88 return parentui.config(section, name, default, untrusted)
90 89
91 90 url = req.env['REQUEST_URI'].split('?')[0]
92 91 if not url.endswith('/'):
93 92 url += '/'
94 93 pathinfo = req.env.get('PATH_INFO', '').strip('/') + '/'
95 94 base = url[:len(url) - len(pathinfo)]
96 95 if not base.endswith('/'):
97 96 base += '/'
98 97
99 98 staticurl = config('web', 'staticurl') or base + 'static/'
100 99 if not staticurl.endswith('/'):
101 100 staticurl += '/'
102 101
103 102 style = self.style
104 103 if style is None:
105 104 style = config('web', 'style', '')
106 105 if req.form.has_key('style'):
107 106 style = req.form['style'][0]
108 107 if self.stripecount is None:
109 108 self.stripecount = int(config('web', 'stripes', 1))
110 109 mapfile = style_map(templater.templatepath(), style)
111 110 tmpl = templater.templater(mapfile, templater.common_filters,
112 111 defaults={"header": header,
113 112 "footer": footer,
114 113 "motd": motd,
115 114 "url": url,
116 115 "staticurl": staticurl})
117 116
118 117 def archivelist(ui, nodeid, url):
119 118 allowed = ui.configlist("web", "allow_archive", untrusted=True)
120 119 for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]:
121 120 if i[0] in allowed or ui.configbool("web", "allow" + i[0],
122 121 untrusted=True):
123 122 yield {"type" : i[0], "extension": i[1],
124 123 "node": nodeid, "url": url}
125 124
126 125 def entries(sortcolumn="", descending=False, subdir="", **map):
127 126 def sessionvars(**map):
128 127 fields = []
129 128 if req.form.has_key('style'):
130 129 style = req.form['style'][0]
131 130 if style != get('web', 'style', ''):
132 131 fields.append(('style', style))
133 132
134 133 separator = url[-1] == '?' and ';' or '?'
135 134 for name, value in fields:
136 135 yield dict(name=name, value=value, separator=separator)
137 136 separator = ';'
138 137
139 138 rows = []
140 139 parity = paritygen(self.stripecount)
141 140 for name, path in self.repos:
142 141 if not name.startswith(subdir):
143 142 continue
144 143 name = name[len(subdir):]
145 144
146 145 u = ui.ui(parentui=parentui)
147 146 try:
148 147 u.readconfig(os.path.join(path, '.hg', 'hgrc'))
149 148 except IOError:
150 149 pass
151 150 def get(section, name, default=None):
152 151 return u.config(section, name, default, untrusted=True)
153 152
154 153 if u.configbool("web", "hidden", untrusted=True):
155 154 continue
156 155
157 156 url = ('/'.join([req.env["REQUEST_URI"].split('?')[0], name])
158 157 .replace("//", "/")) + '/'
159 158
160 159 # update time with local timezone
161 160 try:
162 161 d = (get_mtime(path), util.makedate()[1])
163 162 except OSError:
164 163 continue
165 164
166 165 contact = (get("ui", "username") or # preferred
167 166 get("web", "contact") or # deprecated
168 167 get("web", "author", "")) # also
169 168 description = get("web", "description", "")
170 169 name = get("web", "name", name)
171 170 row = dict(contact=contact or "unknown",
172 171 contact_sort=contact.upper() or "unknown",
173 172 name=name,
174 173 name_sort=name,
175 174 url=url,
176 175 description=description or "unknown",
177 176 description_sort=description.upper() or "unknown",
178 177 lastchange=d,
179 178 lastchange_sort=d[1]-d[0],
180 179 sessionvars=sessionvars,
181 180 archives=archivelist(u, "tip", url))
182 181 if (not sortcolumn
183 182 or (sortcolumn, descending) == self.repos_sorted):
184 183 # fast path for unsorted output
185 184 row['parity'] = parity.next()
186 185 yield row
187 186 else:
188 187 rows.append((row["%s_sort" % sortcolumn], row))
189 188 if rows:
190 189 rows.sort()
191 190 if descending:
192 191 rows.reverse()
193 192 for key, row in rows:
194 193 row['parity'] = parity.next()
195 194 yield row
196 195
197 196 def makeindex(req, subdir=""):
198 197 sortable = ["name", "description", "contact", "lastchange"]
199 198 sortcolumn, descending = self.repos_sorted
200 199 if req.form.has_key('sort'):
201 200 sortcolumn = req.form['sort'][0]
202 201 descending = sortcolumn.startswith('-')
203 202 if descending:
204 203 sortcolumn = sortcolumn[1:]
205 204 if sortcolumn not in sortable:
206 205 sortcolumn = ""
207 206
208 207 sort = [("sort_%s" % column,
209 208 "%s%s" % ((not descending and column == sortcolumn)
210 209 and "-" or "", column))
211 210 for column in sortable]
212 211 req.write(tmpl("index", entries=entries, subdir=subdir,
213 212 sortcolumn=sortcolumn, descending=descending,
214 213 **dict(sort)))
215 214
216 215 try:
217 216 virtual = req.env.get("PATH_INFO", "").strip('/')
218 217 if virtual.startswith('static/'):
219 218 static = os.path.join(templater.templatepath(), 'static')
220 219 fname = virtual[7:]
221 220 req.write(staticfile(static, fname, req) or
222 221 tmpl('error', error='%r not found' % fname))
223 222 elif virtual:
224 223 repos = dict(self.repos)
225 224 while virtual:
226 225 real = repos.get(virtual)
227 226 if real:
228 227 req.env['REPO_NAME'] = virtual
229 228 try:
230 229 repo = hg.repository(parentui, real)
231 230 hgweb(repo).run_wsgi(req)
232 231 except IOError, inst:
233 232 req.write(tmpl("error", error=inst.strerror))
234 233 except hg.RepoError, inst:
235 234 req.write(tmpl("error", error=str(inst)))
236 235 return
237 236
238 237 # browse subdirectories
239 238 subdir = virtual + '/'
240 239 if [r for r in repos if r.startswith(subdir)]:
241 240 makeindex(req, subdir)
242 241 return
243 242
244 243 up = virtual.rfind('/')
245 244 if up < 0:
246 245 break
247 246 virtual = virtual[:up]
248 247
249 248 req.write(tmpl("notfound", repo=virtual))
250 249 else:
251 250 if req.form.has_key('static'):
252 251 static = os.path.join(templater.templatepath(), "static")
253 252 fname = req.form['static'][0]
254 253 req.write(staticfile(static, fname, req)
255 254 or tmpl("error", error="%r not found" % fname))
256 255 else:
257 256 makeindex(req)
258 257 finally:
259 258 tmpl = None
@@ -1,79 +1,77 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # This is the mercurial setup script.
4 4 #
5 5 # 'python setup.py install', or
6 6 # 'python setup.py --help' for more options
7 7
8 8 import sys
9 9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 3, 0, 'final'):
10 10 raise SystemExit, "Mercurial requires python 2.3 or later."
11 11
12 12 import os
13 13 from distutils.core import setup, Extension
14 14 from distutils.command.install_data import install_data
15 15
16 16 import mercurial.version
17 import mercurial.demandimport
18 mercurial.demandimport.enable = lambda: None
19 17
20 18 extra = {}
21 19
22 20 # py2exe needs to be installed to work
23 21 try:
24 22 import py2exe
25 23
26 24 # Help py2exe to find win32com.shell
27 25 try:
28 26 import modulefinder
29 27 import win32com
30 28 for p in win32com.__path__[1:]: # Take the path to win32comext
31 29 modulefinder.AddPackagePath("win32com", p)
32 30 pn = "win32com.shell"
33 31 __import__(pn)
34 32 m = sys.modules[pn]
35 33 for p in m.__path__[1:]:
36 34 modulefinder.AddPackagePath(pn, p)
37 35 except ImportError:
38 36 pass
39 37
40 38 extra['console'] = ['hg']
41 39
42 40 except ImportError:
43 41 pass
44 42
45 43 # specify version string, otherwise 'hg identify' will be used:
46 44 version = ''
47 45
48 46 class install_package_data(install_data):
49 47 def finalize_options(self):
50 48 self.set_undefined_options('install',
51 49 ('install_lib', 'install_dir'))
52 50 install_data.finalize_options(self)
53 51
54 52 mercurial.version.remember_version(version)
55 53 cmdclass = {'install_data': install_package_data}
56 54
57 55 setup(name='mercurial',
58 56 version=mercurial.version.get_version(),
59 57 author='Matt Mackall',
60 58 author_email='mpm@selenic.com',
61 59 url='http://selenic.com/mercurial',
62 60 description='Scalable distributed SCM',
63 61 license='GNU GPL',
64 62 packages=['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert'],
65 63 ext_modules=[Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
66 64 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
67 65 Extension('mercurial.base85', ['mercurial/base85.c']),
68 66 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'])],
69 67 data_files=[(os.path.join('mercurial', root),
70 68 [os.path.join(root, file_) for file_ in files])
71 69 for root, dirs, files in os.walk('templates')],
72 70 cmdclass=cmdclass,
73 71 scripts=['hg', 'hgmerge'],
74 72 options=dict(py2exe=dict(packages=['hgext']),
75 73 bdist_mpkg=dict(zipdist=True,
76 74 license='COPYING',
77 75 readme='contrib/macosx/Readme.html',
78 76 welcome='contrib/macosx/Welcome.html')),
79 77 **extra)
General Comments 0
You need to be logged in to leave comments. Login now