##// END OF EJS Templates
plan9: initial support for plan 9 from bell labs...
Steven Stallion -
r16383:f5dd179b default
parent child Browse files
Show More
@@ -0,0 +1,42 b''
1 #!/bin/rc
2 # 9diff - Mercurial extdiff wrapper for diff(1)
3
4 rfork e
5
6 fn getfiles{
7 cd $1 && \
8 for(f in `{du -as | awk '{print $2}'})
9 test -f $f && echo `{cleanname $f}
10 }
11
12 fn usage{
13 echo >[1=2] usage: 9diff [diff options] parent child root
14 exit usage
15 }
16
17 opts=()
18 while(~ $1 -*){
19 opts=($opts $1)
20 shift
21 }
22 if(! ~ $#* 3)
23 usage
24
25 # extdiff will set the parent and child to a single file if there is
26 # only one change. If there are multiple changes, directories will be
27 # set. diff(1) does not cope particularly with directories; instead we
28 # do the recursion ourselves and diff each file individually.
29 if(test -f $1)
30 diff $opts $1 $2
31 if not{
32 # extdiff will create a snapshot of the working copy to prevent
33 # conflicts during the diff. We circumvent this behavior by
34 # diffing against the repository root to produce plumbable
35 # output. This is antisocial.
36 for(f in `{sort -u <{getfiles $1} <{getfiles $2}}){
37 file1=$1/$f; test -f $file1 || file1=/dev/null
38 file2=$3/$f; test -f $file2 || file2=/dev/null
39 diff $opts $file1 $file2
40 }
41 }
42 exit ''
@@ -0,0 +1,39 b''
1 Mercurial for Plan 9 from Bell Labs
2 ===================================
3
4 This directory contains support for Mercurial on Plan 9 from Bell Labs
5 platforms. It is assumed that the version of Python running on these
6 systems supports the ANSI/POSIX Environment (APE). At the time of this
7 writing, the bichued/python port is the most commonly installed version
8 of Python on these platforms. If a native port of Python is ever made,
9 some minor modification will need to be made to support some of the more
10 esoteric requirements of the platform rather than those currently made
11 (cf. posix.py).
12
13 By default, installations will have the factotum extension enabled; this
14 extension permits factotum(4) to act as an authentication agent for
15 HTTP repositories. Additionally, an extdiff command named 9diff is
16 enabled which generates diff(1) compatible output suitable for use with
17 the plumber(4).
18
19 Commit messages are plumbed using E if no editor is defined; users must
20 update the plumbed file to continue, otherwise the hg process must be
21 interrupted.
22
23 Some work remains with regard to documentation. Section 5 manual page
24 references for hgignore and hgrc need to be re-numbered to section 6 (file
25 formats) and a new man page writer should be written to support the
26 Plan 9 man macro set. Until these issues can be resolved, manual pages
27 are elided from the installation.
28
29 Basic install:
30
31 % mk install # do a system-wide install
32 % hg debuginstall # sanity-check setup
33 % hg # see help
34
35 A proto(2) file is included in this directory as an example of how a
36 binary distribution could be packaged, ostensibly with contrib(1).
37
38 See http://mercurial.selenic.com/ for detailed installation
39 instructions, platform-specific notes, and Mercurial user information.
@@ -0,0 +1,5 b''
1 [extensions]
2 extdiff =
3
4 [extdiff]
5 9diff = 9diff -cm $parent $child $root
@@ -0,0 +1,2 b''
1 [extensions]
2 factotum =
@@ -0,0 +1,37 b''
1 APE=/sys/src/ape
2 <$APE/config
3
4 PYTHON=python
5 PYTHONBIN=/rc/bin
6 SH=ape/psh
7
8 PURE=--pure
9 ROOT=../..
10
11 # This is slightly underhanded; Plan 9 does not support GNU gettext nor
12 # does it support dynamically loaded extension modules. We work around
13 # this by calling build_py and build_scripts directly; this avoids
14 # additional platform hacks in setup.py.
15 build:VQ:
16 @{
17 cd $ROOT
18 $SH -c '$PYTHON setup.py $PURE build_py build_scripts'
19 }
20
21 clean:VQ:
22 @{
23 cd $ROOT
24 $SH -c '$PYTHON setup.py $PURE clean --all'
25 }
26
27 install:VQ: build
28 @{
29 cd $ROOT
30 $SH -c '$PYTHON setup.py $PURE install \
31 --install-scripts $PYTHONBIN \
32 --skip-build' \
33 --force
34 }
35 mkdir -p /lib/mercurial/hgrc.d
36 dircp hgrc.d /lib/mercurial/hgrc.d
37 cp 9diff /rc/bin
@@ -0,0 +1,20 b''
1 lib - sys sys
2 mercurial - sys sys
3 hgrc.d - sys sys
4 9diff.rc - sys sys
5 factotum.rc - sys sys
6 rc - sys sys
7 bin - sys sys
8 9diff - sys sys
9 hg - sys sys
10 sys - sys sys
11 lib - sys sys
12 python - sys sys
13 lib - sys sys
14 python2.5 - sys sys
15 site-packages - sys sys
16 hgext - sys sys
17 + - sys sys
18 mercurial - sys sys
19 + - sys sys
20 mercurial-2.1.1-py2.5.egg-info - sys sys
@@ -0,0 +1,120 b''
1 # factotum.py - Plan 9 factotum integration for Mercurial
2 #
3 # Copyright (C) 2012 Steven Stallion <sstallion@gmail.com>
4 #
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the
7 # Free Software Foundation; either version 2 of the License, or (at your
8 # option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 # Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License along
16 # with this program; if not, write to the Free Software Foundation, Inc.,
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18
19 '''http authentication with factotum
20
21 This extension allows the factotum facility on Plan 9 from Bell Labs platforms
22 to provide authentication information for HTTP access. Configuration entries
23 specified in the auth section as well as authentication information provided
24 in the repository URL are fully supported. If no prefix is specified, a value
25 of ``*`` will be assumed.
26
27 By default, keys are specified as::
28
29 proto=pass service=hg prefix=<prefix> user=<username> !password=<password>
30
31 If the factotum extension is unable to read the required key, one will be
32 requested interactively.
33
34 A configuration section is available to customize runtime behavior. By
35 default, these entries are::
36
37 [factotum]
38 mount = /mnt/factotum
39 path = /bin/auth/factotum
40 service = hg
41
42 The mount entry defines the mount point for the factotum file service. The
43 path entry defines the full path to the factotum binary. Lastly, the service
44 entry controls the service name used when reading keys.
45
46 '''
47
48 from mercurial.i18n import _
49 from mercurial.url import passwordmgr
50 from mercurial import httpconnection, urllib2, util
51 import os
52
53 ERRMAX = 128
54
55 def auth_getkey(self, params):
56 if not self.ui.interactive():
57 raise util.Abort(_('factotum not interactive'))
58 if 'user=' not in params:
59 params = '%s user?' % params
60 params = '%s !password?' % params
61 os.system("%s -g '%s'" % (_path, params))
62
63 def auth_getuserpasswd(self, getkey, params):
64 params = 'proto=pass %s' % params
65 while True:
66 fd = os.open('%s/rpc' % _mount, os.O_RDWR)
67 try:
68 try:
69 os.write(fd, 'start %s' % params)
70 l = os.read(fd, ERRMAX).split()
71 if l[0] == 'ok':
72 os.write(fd, 'read')
73 l = os.read(fd, ERRMAX).split()
74 if l[0] == 'ok':
75 return l[1:]
76 except (OSError, IOError):
77 raise util.Abort(_('factotum not responding'))
78 finally:
79 os.close(fd)
80 getkey(self, params)
81
82 def monkeypatch_method(cls):
83 def decorator(func):
84 setattr(cls, func.__name__, func)
85 return func
86 return decorator
87
88 @monkeypatch_method(passwordmgr)
89 def find_user_password(self, realm, authuri):
90 user, passwd = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
91 self, realm, authuri)
92 if user and passwd:
93 self._writedebug(user, passwd)
94 return (user, passwd)
95
96 prefix = ''
97 res = httpconnection.readauthforuri(self.ui, authuri, user)
98 if res:
99 _, auth = res
100 prefix = auth.get('prefix')
101 user, passwd = auth.get('username'), auth.get('password')
102 if not user or not passwd:
103 if not prefix:
104 prefix = '*'
105 params = 'service=%s prefix=%s' % (_service, prefix)
106 if user:
107 params = '%s user=%s' % (params, user)
108 user, passwd = auth_getuserpasswd(self, auth_getkey, params)
109
110 self.add_password(realm, authuri, user, passwd)
111 self._writedebug(user, passwd)
112 return (user, passwd)
113
114 def uisetup(ui):
115 global _mount
116 _mount = ui.config('factotum', 'mount', '/mnt/factotum')
117 global _path
118 _path = ui.config('factotum', 'path', '/bin/auth/factotum')
119 global _service
120 _service = ui.config('factotum', 'service', 'hg')
@@ -28,16 +28,17 b' alphabetical order, later ones overridin'
28 28 paths are given below, settings from earlier paths override later
29 29 ones.
30 30
31 | (Unix, Windows) ``<repo>/.hg/hgrc``
31 | (All) ``<repo>/.hg/hgrc``
32 32
33 33 Per-repository configuration options that only apply in a
34 34 particular repository. This file is not version-controlled, and
35 35 will not get transferred during a "clone" operation. Options in
36 36 this file override options in all other configuration files. On
37 Unix, most of this file will be ignored if it doesn't belong to a
38 trusted user or to a trusted group. See the documentation for the
39 ``[trusted]`` section below for more details.
37 Plan 9 and Unix, most of this file will be ignored if it doesn't
38 belong to a trusted user or to a trusted group. See the documentation
39 for the ``[trusted]`` section below for more details.
40 40
41 | (Plan 9) ``$home/lib/hgrc``
41 42 | (Unix) ``$HOME/.hgrc``
42 43 | (Windows) ``%USERPROFILE%\.hgrc``
43 44 | (Windows) ``%USERPROFILE%\Mercurial.ini``
@@ -50,6 +51,8 b' ones.'
50 51 directory. Options in these files override per-system and per-installation
51 52 options.
52 53
54 | (Plan 9) ``/lib/mercurial/hgrc``
55 | (Plan 9) ``/lib/mercurial/hgrc.d/*.rc``
53 56 | (Unix) ``/etc/mercurial/hgrc``
54 57 | (Unix) ``/etc/mercurial/hgrc.d/*.rc``
55 58
@@ -58,6 +61,8 b' ones.'
58 61 executed by any user in any directory. Options in these files
59 62 override per-installation options.
60 63
64 | (Plan 9) ``<install-root>/lib/mercurial/hgrc``
65 | (Plan 9) ``<install-root>/lib/mercurial/hgrc.d/*.rc``
61 66 | (Unix) ``<install-root>/etc/mercurial/hgrc``
62 67 | (Unix) ``<install-root>/etc/mercurial/hgrc.d/*.rc``
63 68
@@ -333,6 +333,9 b' def findexe(command):'
333 333 if os.sep in command:
334 334 return findexisting(command)
335 335
336 if sys.platform == 'plan9':
337 return findexisting(os.path.join('/bin', command))
338
336 339 for path in os.environ.get('PATH', '').split(os.pathsep):
337 340 executable = findexisting(os.path.join(path, command))
338 341 if executable is not None:
@@ -436,15 +436,22 b" if os.name != 'nt':"
436 436
437 437 def systemrcpath():
438 438 path = []
439 if sys.platform == 'plan9':
440 root = '/lib/mercurial'
441 else:
442 root = '/etc/mercurial'
439 443 # old mod_python does not set sys.argv
440 444 if len(getattr(sys, 'argv', [])) > 0:
441 445 p = os.path.dirname(os.path.dirname(sys.argv[0]))
442 path.extend(rcfiles(os.path.join(p, 'etc/mercurial')))
443 path.extend(rcfiles('/etc/mercurial'))
446 path.extend(rcfiles(os.path.join(p, root)))
447 path.extend(rcfiles(root))
444 448 return path
445 449
446 450 def userrcpath():
447 return [os.path.expanduser('~/.hgrc')]
451 if sys.platform == 'plan9':
452 return [os.environ['home'] + '/lib/hgrc']
453 else:
454 return [os.path.expanduser('~/.hgrc')]
448 455
449 456 else:
450 457
@@ -687,10 +687,17 b' class ui(object):'
687 687
688 688 def geteditor(self):
689 689 '''return editor to use'''
690 if sys.platform == 'plan9':
691 # vi is the MIPS instruction simulator on Plan 9. We
692 # instead default to E to plumb commit messages to
693 # avoid confusion.
694 editor = 'E'
695 else:
696 editor = 'vi'
690 697 return (os.environ.get("HGEDITOR") or
691 698 self.config("ui", "editor") or
692 699 os.environ.get("VISUAL") or
693 os.environ.get("EDITOR", "vi"))
700 os.environ.get("EDITOR", editor))
694 701
695 702 def progress(self, topic, pos, item="", unit="", total=None):
696 703 '''show a progress message
@@ -422,22 +422,29 b' def system(cmd, environ={}, cwd=None, on'
422 422 return str(val)
423 423 origcmd = cmd
424 424 cmd = quotecommand(cmd)
425 env = dict(os.environ)
426 env.update((k, py2shell(v)) for k, v in environ.iteritems())
427 env['HG'] = hgexecutable()
428 if out is None or out == sys.__stdout__:
429 rc = subprocess.call(cmd, shell=True, close_fds=closefds,
430 env=env, cwd=cwd)
425 if sys.platform == 'plan9':
426 # subprocess kludge to work around issues in half-baked Python
427 # ports, notably bichued/python:
428 if not cwd is None:
429 os.chdir(cwd)
430 rc = os.system(cmd)
431 431 else:
432 proc = subprocess.Popen(cmd, shell=True, close_fds=closefds,
433 env=env, cwd=cwd, stdout=subprocess.PIPE,
434 stderr=subprocess.STDOUT)
435 for line in proc.stdout:
436 out.write(line)
437 proc.wait()
438 rc = proc.returncode
439 if sys.platform == 'OpenVMS' and rc & 1:
440 rc = 0
432 env = dict(os.environ)
433 env.update((k, py2shell(v)) for k, v in environ.iteritems())
434 env['HG'] = hgexecutable()
435 if out is None or out == sys.__stdout__:
436 rc = subprocess.call(cmd, shell=True, close_fds=closefds,
437 env=env, cwd=cwd)
438 else:
439 proc = subprocess.Popen(cmd, shell=True, close_fds=closefds,
440 env=env, cwd=cwd, stdout=subprocess.PIPE,
441 stderr=subprocess.STDOUT)
442 for line in proc.stdout:
443 out.write(line)
444 proc.wait()
445 rc = proc.returncode
446 if sys.platform == 'OpenVMS' and rc & 1:
447 rc = 0
441 448 if rc and onerr:
442 449 errmsg = '%s %s' % (os.path.basename(origcmd.split(None, 1)[0]),
443 450 explainexit(rc)[0])
@@ -127,10 +127,16 b' except ImportError:'
127 127 py2exeloaded = False
128 128
129 129 def runcmd(cmd, env):
130 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
131 stderr=subprocess.PIPE, env=env)
132 out, err = p.communicate()
133 return out, err
130 if sys.platform == 'plan9':
131 # subprocess kludge to work around issues in half-baked Python
132 # ports, notably bichued/python:
133 _, out, err = os.popen3(cmd)
134 return str(out), str(err)
135 else:
136 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
137 stderr=subprocess.PIPE, env=env)
138 out, err = p.communicate()
139 return out, err
134 140
135 141 def runhg(cmd, env):
136 142 out, err = runcmd(cmd, env)
@@ -1,7 +1,7 b''
1 1 import os
2 2 from mercurial import ui, commands, extensions
3 3
4 ignore = set(['highlight', 'inotify', 'win32text'])
4 ignore = set(['highlight', 'inotify', 'win32text', 'factotum'])
5 5
6 6 if os.name != 'nt':
7 7 ignore.add('win32mbcs')
General Comments 0
You need to be logged in to leave comments. Login now