##// END OF EJS Templates
Merge with crew-stable
Patrick Mezard -
r5321:639935f2 merge default
parent child Browse files
Show More
@@ -1,78 +1,78
1 # statichttprepo.py - simple http repository class for mercurial
1 # statichttprepo.py - simple http repository class for mercurial
2 #
2 #
3 # This provides read-only repo access to repositories exported via static http
3 # This provides read-only repo access to repositories exported via static http
4 #
4 #
5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms
7 # This software may be used and distributed according to the terms
8 # of the GNU General Public License, incorporated herein by reference.
8 # of the GNU General Public License, incorporated herein by reference.
9
9
10 from i18n import _
10 from i18n import _
11 import changelog, filelog, httprangereader
11 import changelog, filelog, httprangereader
12 import repo, localrepo, manifest, os, urllib, urllib2, util
12 import repo, localrepo, manifest, os, urllib, urllib2, util
13
13
14 class rangereader(httprangereader.httprangereader):
14 class rangereader(httprangereader.httprangereader):
15 def read(self, size=None):
15 def read(self, size=None):
16 try:
16 try:
17 return httprangereader.httprangereader.read(self, size)
17 return httprangereader.httprangereader.read(self, size)
18 except urllib2.HTTPError, inst:
18 except urllib2.HTTPError, inst:
19 raise IOError(None, inst)
19 raise IOError(None, inst)
20 except urllib2.URLError, inst:
20 except urllib2.URLError, inst:
21 raise IOError(None, inst.reason[1])
21 raise IOError(None, inst.reason[1])
22
22
23 def opener(base):
23 def opener(base):
24 """return a function that opens files over http"""
24 """return a function that opens files over http"""
25 p = base
25 p = base
26 def o(path, mode="r"):
26 def o(path, mode="r"):
27 f = "/".join((p, urllib.quote(path)))
27 f = "/".join((p, urllib.quote(path)))
28 return rangereader(f)
28 return rangereader(f)
29 return o
29 return o
30
30
31 class statichttprepository(localrepo.localrepository):
31 class statichttprepository(localrepo.localrepository):
32 def __init__(self, ui, path):
32 def __init__(self, ui, path):
33 self._url = path
33 self._url = path
34 self.ui = ui
34 self.ui = ui
35
35
36 self.path = (path + "/.hg")
36 self.path = path.rstrip('/') + "/.hg"
37 self.opener = opener(self.path)
37 self.opener = opener(self.path)
38 # find requirements
38 # find requirements
39 try:
39 try:
40 requirements = self.opener("requires").read().splitlines()
40 requirements = self.opener("requires").read().splitlines()
41 except IOError:
41 except IOError:
42 requirements = []
42 requirements = []
43 # check them
43 # check them
44 for r in requirements:
44 for r in requirements:
45 if r not in self.supported:
45 if r not in self.supported:
46 raise repo.RepoError(_("requirement '%s' not supported") % r)
46 raise repo.RepoError(_("requirement '%s' not supported") % r)
47
47
48 # setup store
48 # setup store
49 if "store" in requirements:
49 if "store" in requirements:
50 self.encodefn = util.encodefilename
50 self.encodefn = util.encodefilename
51 self.decodefn = util.decodefilename
51 self.decodefn = util.decodefilename
52 self.spath = self.path + "/store"
52 self.spath = self.path + "/store"
53 else:
53 else:
54 self.encodefn = lambda x: x
54 self.encodefn = lambda x: x
55 self.decodefn = lambda x: x
55 self.decodefn = lambda x: x
56 self.spath = self.path
56 self.spath = self.path
57 self.sopener = util.encodedopener(opener(self.spath), self.encodefn)
57 self.sopener = util.encodedopener(opener(self.spath), self.encodefn)
58
58
59 self.manifest = manifest.manifest(self.sopener)
59 self.manifest = manifest.manifest(self.sopener)
60 self.changelog = changelog.changelog(self.sopener)
60 self.changelog = changelog.changelog(self.sopener)
61 self.tagscache = None
61 self.tagscache = None
62 self.nodetagscache = None
62 self.nodetagscache = None
63 self.encodepats = None
63 self.encodepats = None
64 self.decodepats = None
64 self.decodepats = None
65
65
66 def url(self):
66 def url(self):
67 return 'static-' + self._url
67 return 'static-' + self._url
68
68
69 def dev(self):
69 def dev(self):
70 return -1
70 return -1
71
71
72 def local(self):
72 def local(self):
73 return False
73 return False
74
74
75 def instance(ui, path, create):
75 def instance(ui, path, create):
76 if create:
76 if create:
77 raise util.Abort(_('cannot create new static-http repository'))
77 raise util.Abort(_('cannot create new static-http repository'))
78 return statichttprepository(ui, path[7:])
78 return statichttprepository(ui, path[7:])
@@ -1,52 +1,66
1 #!/bin/sh
1 #!/bin/sh
2
2
3 cp "$TESTDIR"/printenv.py .
3 cp "$TESTDIR"/printenv.py .
4
4
5 http_proxy= hg clone static-http://localhost:20059/ copy
5 http_proxy= hg clone static-http://localhost:20059/ copy
6 echo $?
6 echo $?
7 test -d copy || echo copy: No such file or directory
7 test -d copy || echo copy: No such file or directory
8
8
9 # This server doesn't do range requests so it's basically only good for
9 # This server doesn't do range requests so it's basically only good for
10 # one pull
10 # one pull
11 cat > dumb.py <<EOF
11 cat > dumb.py <<EOF
12 import BaseHTTPServer, SimpleHTTPServer, signal
12 import BaseHTTPServer, SimpleHTTPServer, signal
13
13
14 def run(server_class=BaseHTTPServer.HTTPServer,
14 def run(server_class=BaseHTTPServer.HTTPServer,
15 handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler):
15 handler_class=SimpleHTTPServer.SimpleHTTPRequestHandler):
16 server_address = ('localhost', 20059)
16 server_address = ('localhost', 20059)
17 httpd = server_class(server_address, handler_class)
17 httpd = server_class(server_address, handler_class)
18 httpd.serve_forever()
18 httpd.serve_forever()
19
19
20 signal.signal(signal.SIGTERM, lambda x: sys.exit(0))
20 signal.signal(signal.SIGTERM, lambda x: sys.exit(0))
21 run()
21 run()
22 EOF
22 EOF
23
23
24 python dumb.py 2>/dev/null &
24 python dumb.py 2>/dev/null &
25 echo $! >> $DAEMON_PIDS
25 echo $! >> $DAEMON_PIDS
26
26
27 mkdir remote
27 mkdir remote
28 cd remote
28 cd remote
29 hg init
29 hg init
30 echo foo > bar
30 echo foo > bar
31 hg add bar
31 hg add bar
32 hg commit -m"test" -d "1000000 0"
32 hg commit -m"test" -d "1000000 0"
33 hg tip
33 hg tip
34
34
35 cd ..
35 cd ..
36
36
37 http_proxy= hg clone static-http://localhost:20059/remote local
37 http_proxy= hg clone static-http://localhost:20059/remote local
38
38
39 cd local
39 cd local
40 hg verify
40 hg verify
41 cat bar
41 cat bar
42
42
43 cd ../remote
43 cd ../remote
44 echo baz > quux
44 echo baz > quux
45 hg commit -A -mtest2 -d '100000000 0'
45 hg commit -A -mtest2 -d '100000000 0'
46
46
47 cd ../local
47 cd ../local
48 echo '[hooks]' >> .hg/hgrc
48 echo '[hooks]' >> .hg/hgrc
49 echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
49 echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
50 http_proxy= hg pull
50 http_proxy= hg pull
51
51
52 echo '% test with "/" URI (issue 747)'
53 cd ..
54 hg init
55 echo a > a
56 hg add a
57 hg ci -ma
58
59 http_proxy= hg clone static-http://localhost:20059/ local2
60
61 cd local2
62 hg verify
63 cat a
64 hg paths
65
52 kill $!
66 kill $!
@@ -1,30 +1,44
1 abort: Connection refused
1 abort: Connection refused
2 255
2 255
3 copy: No such file or directory
3 copy: No such file or directory
4 changeset: 0:53e17d176ae6
4 changeset: 0:53e17d176ae6
5 tag: tip
5 tag: tip
6 user: test
6 user: test
7 date: Mon Jan 12 13:46:40 1970 +0000
7 date: Mon Jan 12 13:46:40 1970 +0000
8 summary: test
8 summary: test
9
9
10 requesting all changes
10 requesting all changes
11 adding changesets
11 adding changesets
12 adding manifests
12 adding manifests
13 adding file changes
13 adding file changes
14 added 1 changesets with 1 changes to 1 files
14 added 1 changesets with 1 changes to 1 files
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
15 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 checking changesets
16 checking changesets
17 checking manifests
17 checking manifests
18 crosschecking files in changesets and manifests
18 crosschecking files in changesets and manifests
19 checking files
19 checking files
20 1 files, 1 changesets, 1 total revisions
20 1 files, 1 changesets, 1 total revisions
21 foo
21 foo
22 adding quux
22 adding quux
23 changegroup hook: HG_NODE=34401e0e9971e9720b613d9089ffa9a6eefb3d2d HG_SOURCE=pull HG_URL=static-http://localhost:20059/remote
23 changegroup hook: HG_NODE=34401e0e9971e9720b613d9089ffa9a6eefb3d2d HG_SOURCE=pull HG_URL=static-http://localhost:20059/remote
24 pulling from static-http://localhost:20059/remote
24 pulling from static-http://localhost:20059/remote
25 searching for changes
25 searching for changes
26 adding changesets
26 adding changesets
27 adding manifests
27 adding manifests
28 adding file changes
28 adding file changes
29 added 1 changesets with 1 changes to 1 files
29 added 1 changesets with 1 changes to 1 files
30 (run 'hg update' to get a working copy)
30 (run 'hg update' to get a working copy)
31 % test with "/" URI (issue 747)
32 requesting all changes
33 adding changesets
34 adding manifests
35 adding file changes
36 added 1 changesets with 1 changes to 1 files
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 checking changesets
39 checking manifests
40 crosschecking files in changesets and manifests
41 checking files
42 1 files, 1 changesets, 1 total revisions
43 a
44 default = static-http://localhost:20059/
General Comments 0
You need to be logged in to leave comments. Login now