A => .flake8 +2 -0
@@ 0,0 1,2 @@
+[flake8]
+max-line-length = 88
M hgext3rd/confman/__init__.py +17 -15
@@ 6,23 6,24 @@ or in the REAMDE.md file.
testedwith = '5.8 5.9 6.0 6.1 6.2 6.3'
import os.path as osp
+
from mercurial import extensions
+from .commands import *
from .meta import colortable
-from .commands import *
-
-
configtable = {}
configitem = registrar.configitem(configtable)
-configitem(b'confman', b'hggit',
- default=True,
+configitem(
+ b'confman',
+ b'hggit',
+ default=True,
)
def extsetup(ui):
- """ add confman support to hgview """
+ """add confman support to hgview"""
try:
extensions.find(b'hgview')
except KeyError:
@@ 31,19 32,20 @@ def extsetup(ui):
from hgviewlib.util import SUBREPO_GETTERS
except ImportError:
return
+
def _get_confman(repo_path):
- """ return mapping of section -> path
- for all managed repositories """
+ """return mapping of section -> path
+ for all managed repositories"""
confpath = osp.join(repo_path, '.hgconf')
if not osp.exists(confpath):
return None
from .configuration import configurationmanager
+
confman = configurationmanager(ui, repo_path, (), {})
- return ((section, conf.get('layout'))
- for section, conf, managed in confman.iterrepos()
- if (managed is not None or
- conf.get('expand', None) is not None))
+ return (
+ (section, conf.get('layout'))
+ for section, conf, managed in confman.iterrepos()
+ if (managed is not None or conf.get('expand', None) is not None)
+ )
+
SUBREPO_GETTERS.append(_get_confman)
-
-
-
M hgext3rd/confman/commands.py +125 -100
@@ 3,28 3,12 @@ import os
import os.path as osp
import sys
-from mercurial import (
- error,
- registrar
-)
+from mercurial import error, registrar
from mercurial.i18n import _
-from .utils import (
- readconf,
- WrappedUI,
- WrappedRepo
-)
-from .managed import (
- gitrepo,
- hgrepo
-)
-from .opts import (
- DEFAULTOPTS,
- EXCLUDEOPT,
- INCLUDEOPT,
- PULLURIOPT,
- REMOTEOPTS
-)
+from .managed import gitrepo, hgrepo
+from .opts import DEFAULTOPTS, EXCLUDEOPT, INCLUDEOPT, PULLURIOPT, REMOTEOPTS
+from .utils import WrappedRepo, WrappedUI, readconf
ENC = os.environ.get('ENCODING')
@@ 35,46 19,45 @@ cmdtable = {}
def command(name, opts):
name = name.encode('utf-8')
newopts = [
- tuple(item.encode('utf-8')
- if isinstance(item, str) else item
- for item in elt)
+ tuple(item.encode('utf-8') if isinstance(item, str) else item for item in elt)
for elt in opts
]
def wrap_command(func):
def wrapped_func(ui, repo, *args, **kw):
- newargs = tuple(
- elt.decode('utf-8')
- for elt in args
- )
+ newargs = tuple(elt.decode('utf-8') for elt in args)
newk = {}
for k, v in kw.items():
if isinstance(v, bytes):
v = v.decode('utf-8')
elif isinstance(v, list):
v = [
- elt.decode('utf-8')
- if isinstance(elt, bytes) else elt
+ elt.decode('utf-8') if isinstance(elt, bytes) else elt
for elt in v
]
newk[k] = v
- return func(
- WrappedUI(ui),
- WrappedRepo(repo),
- *newargs,
- **newk
- )
+ return func(WrappedUI(ui), WrappedRepo(repo), *newargs, **newk)
+
wrapped_func.__doc__ = func.__doc__
return _command(name, newopts)(wrapped_func)
return wrap_command
-@command('cfensureconf',
- DEFAULTOPTS + REMOTEOPTS + [
- ('s', 'share-path', '', 'specify share path'),
- ('', 'keep-descendant', False,
- 'do not update managed if it is on a descendant of track')])
+@command(
+ 'cfensureconf',
+ DEFAULTOPTS
+ + REMOTEOPTS
+ + [
+ ('s', 'share-path', '', 'specify share path'),
+ (
+ '',
+ 'keep-descendant',
+ False,
+ 'do not update managed if it is on a descendant of track',
+ ),
+ ],
+)
def ensureconf(ui, repo, *args, **opts):
"""update managed repositories using their track value
@@ 104,7 87,7 @@ def ensureconf(ui, repo, *args, **opts):
snapshot = snaps.get(layout)
wctx = managed.workingctx()
if wctx.hex == snapshot:
- continue # already up to date
+ continue # already up to date
if managed.check_dirty(section):
failedrepos.append(section)
continue
@@ 122,13 105,19 @@ def ensureconf(ui, repo, *args, **opts):
if failedrepos:
return 1
+
# baseline
-@command('cfbaseline',
- DEFAULTOPTS + [
- ('', 'force-hgconf', False, 'force the generation of an .hgconf file'),
- ('', 'propagate', False, 'edit inner configuration also'),
- ('Z', 'ignoremaster', True, 'ignore the <origin>/master tag')])
+
+@command(
+ 'cfbaseline',
+ DEFAULTOPTS
+ + [
+ ('', 'force-hgconf', False, 'force the generation of an .hgconf file'),
+ ('', 'propagate', False, 'edit inner configuration also'),
+ ('Z', 'ignoremaster', True, 'ignore the <origin>/master tag'),
+ ],
+)
def baseline(ui, repo, *args, **opts):
"""update the track attributes with cset hashes or matching tags
@@ 195,9 184,10 @@ def baseline(ui, repo, *args, **opts):
# pull
+
@command('cfpull', DEFAULTOPTS + REMOTEOPTS)
def pull(ui, repo, *args, **opts):
- """pull managed repositories """
+ """pull managed repositories"""
confman, repo = readconf(ui, repo, args, opts)
for section, conf, managed in confman.iterrepos():
@@ 214,9 204,10 @@ def pull(ui, repo, *args, **opts):
# push
+
@command('cfpush', DEFAULTOPTS + REMOTEOPTS)
def push(ui, repo, *args, **opts):
- """push managed repositories up to their tracked rev """
+ """push managed repositories up to their tracked rev"""
confman, repo = readconf(ui, repo, args, opts)
for section, conf, managed in confman.iterrepos():
@@ 225,8 216,10 @@ def push(ui, repo, *args, **opts):
continue
managed.push_repo(section, conf)
+
# summary
+
@command('cfsummary', DEFAULTOPTS)
def summary(ui, repo, *args, **opts):
"""print a summary of the managed repositories
@@ 252,7 245,7 @@ def summary(ui, repo, *args, **opts):
phase = rctx.phase
if phase:
- ui.write(' ')
+ ui.write(' ')
ui.write('%s' % phase, label='confman.%s-phase' % phase)
ui.write(') ')
@@ 271,31 264,39 @@ def summary(ui, repo, *args, **opts):
track = conf.get('track')
trackctx = managed.revsingle(track, skiperror=True)
if track is None:
- ui.write('[no baseline]',
- label='confman.nobaseline')
+ ui.write('[no baseline]', label='confman.nobaseline')
elif track == branch:
- ui.write('[baseline aligned with branch]',
- label='confman.branchaligned')
+ ui.write('[baseline aligned with branch]', label='confman.branchaligned')
elif track in tags:
ui.write_bytes(
'\N{CHECK MARK}'.encode(ENC or sys.stdout.encoding, 'confman'),
- label='confman.tagaligned'
+ label='confman.tagaligned',
)
elif track == str(rctx.revnum) or rctx.hex.startswith(track):
- ui.write('[baseline aligned with%s cset %s]' % (obs(trackctx), track[:12]),
- label='confman.csetaligned')
+ ui.write(
+ '[baseline aligned with%s cset %s]' % (obs(trackctx), track[:12]),
+ label='confman.csetaligned',
+ )
elif trackctx == rctx:
- ui.write('[baseline aligned with revset %r]' % track,
- label='confman.revsetaligned')
+ ui.write(
+ '[baseline aligned with revset %r]' % track,
+ label='confman.revsetaligned',
+ )
elif trackctx in rctx.ancestors():
- ui.write('[at descendant of%s %r]' % (obs(trackctx), track),
- label='confman.snapolder')
+ ui.write(
+ '[at descendant of%s %r]' % (obs(trackctx), track),
+ label='confman.snapolder',
+ )
elif trackctx in rctx.descendants():
- ui.write('[at parent of%s %r]' % (obs(trackctx), track),
- label='confman.snapnewer')
+ ui.write(
+ '[at parent of%s %r]' % (obs(trackctx), track),
+ label='confman.snapnewer',
+ )
elif trackctx:
- ui.write('[baseline%s %r in a parallel branch]' % (obs(trackctx), track),
- label='confman.snapparallel')
+ ui.write(
+ '[baseline%s %r in a parallel branch]' % (obs(trackctx), track),
+ label='confman.snapparallel',
+ )
else:
ui.write('[baseline says %r]' % track, label='confman.unaligned')
@@ 330,8 331,8 @@ def summary(ui, repo, *args, **opts):
# broadcast
-@command('cfbroadcast', DEFAULTOPTS + [
- ('e', 'execute', [], 'execute command')])
+
+@command('cfbroadcast', DEFAULTOPTS + [('e', 'execute', [], 'execute command')])
def broadcast(ui, repo, *args, **opts):
"""execute a shell command in the context of managed repositories
@@ 364,24 365,36 @@ def broadcast(ui, repo, *args, **opts):
try:
command = command % params
except KeyError as err:
- ui.write('skip %s: unknown parameter %s\n' % (section, err),
- label='confman.dirty')
+ ui.write(
+ 'skip %s: unknown parameter %s\n' % (section, err),
+ label='confman.dirty',
+ )
continue
- proc = subprocess.Popen(command, shell=True,
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=confman.pathfromsection(section))
+ proc = subprocess.Popen(
+ command,
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ cwd=confman.pathfromsection(section),
+ )
out, err = proc.communicate()
ui.write_bytes(out)
if proc.returncode != 0:
- ui.write('finished with return code %s\n' % proc.returncode,
- label='confman.dirty')
+ ui.write(
+ 'finished with return code %s\n' % proc.returncode,
+ label='confman.dirty',
+ )
-@command('cffiles', DEFAULTOPTS + [
- ('n', 'no-section', False, 'do not display section name'),
- ('0', 'print0', False, 'end filenames with NUL, for use with xargs')])
+@command(
+ 'cffiles',
+ DEFAULTOPTS
+ + [
+ ('n', 'no-section', False, 'do not display section name'),
+ ('0', 'print0', False, 'end filenames with NUL, for use with xargs'),
+ ],
+)
def files(ui, repo, *args, **opts):
"""list tracked files in the managed repositories
@@ 403,9 416,15 @@ def files(ui, repo, *args, **opts):
# rewrite repo conf
-@command('cfupdateconf', DEFAULTOPTS + [
- ('', 'difftool', 'diff', 'diff command'),
- ('a', 'apply', False, 'really apply the changes (irreversible)')])
+
+@command(
+ 'cfupdateconf',
+ DEFAULTOPTS
+ + [
+ ('', 'difftool', 'diff', 'diff command'),
+ ('a', 'apply', False, 'really apply the changes (irreversible)'),
+ ],
+)
def updateconf(ui, repo, *args, **opts):
"""update your managed repos `.hg/hgrc` files with values of the `.hgconf` entries
@@ 431,12 450,18 @@ def updateconf(ui, repo, *args, **opts):
# requirements.txt handling
-@command('debugcfrequirements', [
- INCLUDEOPT, EXCLUDEOPT, PULLURIOPT,
- ('e', 'editable', False, 'use local project path or and develop mode')])
+
+@command(
+ 'debugcfrequirements',
+ [
+ INCLUDEOPT,
+ EXCLUDEOPT,
+ PULLURIOPT,
+ ('e', 'editable', False, 'use local project path or and develop mode'),
+ ],
+)
def requirements(ui, repo, *args, **opts):
- """generate a requirements.txt file from the .hgconf specification
- """
+ """generate a requirements.txt file from the .hgconf specification"""
confman, repo = readconf(ui, repo, args, opts)
with open('requirements.txt', 'wb') as req:
@@ 451,12 476,16 @@ def requirements(ui, repo, *args, **opts
prefix, suffix = 'git+', '@' + conf.get('track', 'default')
else:
prefix, suffix = '', ''
- uri = conf.get('hgrc.paths.%s' % opts.get('use_hgrc_path')) or conf['pulluri']
+ uri = (
+ conf.get('hgrc.paths.%s' % opts.get('use_hgrc_path'))
+ or conf['pulluri']
+ )
req.write('%s%s%s\n' % (prefix, uri.format(**conf), suffix))
# DEPRECATED
+
@command('debugsnapshot', DEFAULTOPTS)
def snapshot(ui, repo, *args, **opts):
"""record changeset ids of the managed repositories into the `.hgsnap` file
@@ 480,23 509,17 @@ def snapshot(ui, repo, *args, **opts):
def showsnapshotstate(self, ui, snapshot, rctx):
snaprctx = self.revsingle(snapshot, skiperror=True)
if snapshot is None:
- ui.write('[no snapshot]',
- label='confman.nosnap')
+ ui.write('[no snapshot]', label='confman.nosnap')
elif self.unknown_rev(snapshot):
- ui.write('[unknown snapshot]',
- label='confman.snapunknown')
+ ui.write('[unknown snapshot]', label='confman.snapunknown')
elif rctx == snaprctx:
- ui.write('[snapshot aligned]',
- label='confman.snapaligned')
+ ui.write('[snapshot aligned]', label='confman.snapaligned')
elif snaprctx in rctx.ancestors():
- ui.write('[at descendant of snapshot]',
- label='confman.snapolder')
+ ui.write('[at descendant of snapshot]', label='confman.snapolder')
elif snaprctx in rctx.descendants():
- ui.write('[at parent of snapshot]',
- label='confman.snapnewer')
+ ui.write('[at parent of snapshot]', label='confman.snapnewer')
else:
- ui.write('[snapshot in parallel branch]',
- label='confman.snapparallel')
+ ui.write('[snapshot in parallel branch]', label='confman.snapparallel')
@command('debugwritegrfiles', DEFAULTOPTS + [PULLURIOPT])
@@ 512,7 535,9 @@ def writegrfiles(ui, repo, *args, **opts
track = secconf.get('track')
pulluri = secconf.get('pulluri')
if opts.get('use_hgrc_path'):
- pulluri = secconf.get('hgrc.paths.' + opts.get('use_hgrc_path'), pulluri)
+ pulluri = secconf.get(
+ 'hgrc.paths.' + opts.get('use_hgrc_path'), pulluri
+ )
try:
ctx = managed.revsingle(track)
track = ctx.tag or ctx.hex
M hgext3rd/confman/configuration.py +45 -38
@@ 1,11 1,12 @@
"""This module contains the configurationmanager object."""
+import itertools
import os
-import itertools
from collections import defaultdict
-from mercurial import util, error
-from .meta import MANDATORY, CONFMANENTRIES
+from mercurial import error, util
+
+from .meta import CONFMANENTRIES, MANDATORY
from .utils import ending
@@ 28,18 29,18 @@ def _filtersection(section, exactmatch=(
return False
return True
+
STATUSMAP = {
0: ' ',
1: '\N{BOX DRAWINGS LIGHT VERTICAL} ',
2: '\N{BOX DRAWINGS LIGHT UP AND RIGHT}\N{RIGHTWARDS ARROW} ',
- 3: '\N{BOX DRAWINGS LIGHT VERTICAL AND RIGHT}\N{RIGHTWARDS ARROW} '
- }
+ 3: '\N{BOX DRAWINGS LIGHT VERTICAL AND RIGHT}\N{RIGHTWARDS ARROW} ',
+}
class configurationmanager(object):
"Configuration manager"
- __slots__ = ('ui', 'rootpath', 'args', 'opts',
- 'confs', 'failed', 'sectionlevels')
+ __slots__ = ('ui', 'rootpath', 'args', 'opts', 'confs', 'failed', 'sectionlevels')
def __init__(self, ui, rootpath, args, opts):
self.ui = ui
@@ 62,6 63,7 @@ class configurationmanager(object):
def _readconf(self):
"Load configuration from <root>/.hgconf"
from .utils import oconfig
+
self.confs = oconfig(confman=self)
self.confs.read(os.path.join(self.rootpath, '.hgconf'))
@@ 72,17 74,21 @@ class configurationmanager(object):
ui = self.ui
if not skipmissing:
ui.warn('You must complete the configuration before using it. See:\n')
- ui.warn(''.join('error: %s.%s is missing\n' % (section, opt) for opt in err))
+ ui.warn(
+ ''.join('error: %s.%s is missing\n' % (section, opt) for opt in err)
+ )
raise error.Abort(b'configuration error')
else:
ui.warn('%s is a partial override without its master entry\n' % section)
return True
def pathfromsection(self, section):
- "Return the path of the repository managed at ``section`` "
- rootpath = (self.opts.get('root_path') or
- self.ui.configpath('confman', 'rootpath') or
- self.rootpath)
+ "Return the path of the repository managed at ``section``"
+ rootpath = (
+ self.opts.get('root_path')
+ or self.ui.configpath('confman', 'rootpath')
+ or self.rootpath
+ )
conf = self.confs[section]
layout = conf['layout'].format(**conf)
return os.path.join(rootpath, layout)
@@ 92,12 98,15 @@ class configurationmanager(object):
None if the repository is missing.
Raise RepoError if the repository cannot be built."""
from .managed import repoclassbyconf
+
path = self.pathfromsection(section)
if not os.path.exists(path):
return None
try:
return repoclassbyconf(
- self.confs[section], path, self.hggit,
+ self.confs[section],
+ path,
+ self.hggit,
)(self, path)
except error.RepoError:
return None
@@ 129,8 138,7 @@ class configurationmanager(object):
managed = self.repofromsection(section)
if managed is None and skipmissing:
path = self.pathfromsection(section)
- self.ui.write('%s repository at "%s" not found\n' %
- (section, path))
+ self.ui.write('%s repository at "%s" not found\n' % (section, path))
continue
yield section, conf, managed
if conf.get('expand', None):
@@ 173,6 181,7 @@ class configurationmanager(object):
def fill_missing(self):
"Try to clone the missing managed repositories if possible"
from .managed import repoclassbyconf
+
ui = self.ui
# catches simple rev ids but NOT revexprs
for section, conf, managed in self.iterrepos(skipmissing=False):
@@ 186,9 195,7 @@ class configurationmanager(object):
ui.status('cloning %s from %s to %s\n' % (section, source, dest))
try:
path = self.pathfromsection(section)
- repoclassbyconf(
- conf, path, self.hggit
- ).clone(
+ repoclassbyconf(conf, path, self.hggit).clone(
self, source, dest, self.confs[section]
)
except Exception as err:
@@ 210,29 217,27 @@ class configurationmanager(object):
# let's write down those options
self.handle_hgrc(section, conf)
-
@util.cachefunc
def levelstatus(self, section, level):
sectionlevels = self.sectionlevels[section]
sections = self.sections
# sections under scope of the current section
- scope = sections[sections.index(section) + 1:]
+ scope = sections[sections.index(section) + 1 :]
# levels where scoped sessions are
- scopelevels = set(itertools.chain(*(
- self.sectionlevels[s] for s in scope)))
+ scopelevels = set(itertools.chain(*(self.sectionlevels[s] for s in scope)))
if level not in sectionlevels:
if level in scopelevels:
- return 1 # under our scope, not our business
- return 0 # out of scope
- nextsection = (section != sections[-1]
- and sections[sections.index(section)+1]
- or None)
+ return 1 # under our scope, not our business
+ return 0 # out of scope
+ nextsection = (
+ section != sections[-1] and sections[sections.index(section) + 1] or None
+ )
if nextsection:
if not self.levelstatus(nextsection, level):
- return 2 # end of scope
- return 3 # we *override* this
- return 2 # end of scope
+ return 2 # end of scope
+ return 3 # we *override* this
+ return 2 # end of scope
def unicodetreenode(self, section):
"Return the unicode string to print for the given section."
@@ 249,8 254,9 @@ class configurationmanager(object):
"""Handler for the `hgrc` top level optional configuration entries
Will turn any entry such as:
hgrc.paths.foo = http://hg.bar.org
- into a foo entry in the managed repo hgrc [paths] section """
- from .utils import oconfig, _unflatten
+ into a foo entry in the managed repo hgrc [paths] section"""
+ from .utils import _unflatten, oconfig
+
repopath = self.pathfromsection(section)
hgrcpath = os.path.join(repopath, '.hg', 'hgrc')
if not os.path.exists(hgrcpath):
@@ 297,7 303,7 @@ class configurationmanager(object):
rewritten.append((section, tagmap[section]))
newhgconf.write(line)
- if os.name == 'nt': # atomic rename not a windows thing
+ if os.name == 'nt': # atomic rename not a windows thing
os.unlink(hgconfpath)
os.rename(newhgconfpath, hgconfpath)
return rewritten
@@ 309,9 315,7 @@ class configurationmanager(object):
with open(snappath, 'r') as snapfile:
return {
layout: revision.strip()
- for revision, layout in (
- line.split() for line in snapfile
- )
+ for revision, layout in (line.split() for line in snapfile)
}
return {}
@@ 342,8 346,11 @@ class configurationmanager(object):
oldsnaps = self.readsnapshot()
if oldsnaps != snaps:
with open(os.path.join(self.rootpath, '.hgsnap'), 'w') as hgsnapfile:
- hgsnapfile.write(''.join('%s %s\n' % (node, path)
- for path, node in sorted(snaps.items())))
+ hgsnapfile.write(
+ ''.join(
+ '%s %s\n' % (node, path) for path, node in sorted(snaps.items())
+ )
+ )
ui.status('new snapshot in .hgsnap\n')
else:
ui.status('nothing changed\n')
M hgext3rd/confman/gr.py +12 -6
@@ 2,18 2,19 @@
guestrepo extension compatibility support
"""
import os
-from mercurial import config, util, error
+
+from mercurial import config, error, util
+from .configuration import configurationmanager as _configurationmanager
from .utils import ending
-from .configuration import configurationmanager as _configurationmanager
class configurationmanager(_configurationmanager):
"Configuration manager for guestrepo files"
def readsnapshot(self):
- """ return a dict(layout:rev) using the guestrepo
- configuration files """
+ """return a dict(layout:rev) using the guestrepo
+ configuration files"""
grepopath = os.path.join(self.rootpath, '.hgguestrepo')
if os.path.exists(grepopath):
conf = config.config()
@@ 52,10 53,15 @@ class configurationmanager(_configuratio
raise error.Abort(b'Malformed line %s %r' % (lineno + 1, line))
track = tagmap.get(name)
if track is not None and cset != track:
- sline = '%s = %s %s%s' % (layout, name, tagmap[name], ending(sline))
+ sline = '%s = %s %s%s' % (
+ layout,
+ name,
+ tagmap[name],
+ ending(sline),
+ )
rewritten.append((name, track))
newhgguest.write(sline)
- if os.name == 'nt': # atomic rename not a windows thing
+ if os.name == 'nt': # atomic rename not a windows thing
os.unlink(hgguestpath)
os.rename(newhgguestpath, hgguestpath)
return rewritten
M hgext3rd/confman/hgcompat.py +9 -5
@@ 1,13 1,14 @@
"""This version aims to ensure compatibility between multiple version of
mercurial.
"""
-from mercurial.util import sortdict, re as hgre
from mercurial.configitems import coreconfigitem
+from mercurial.util import re as hgre
+from mercurial.util import sortdict
compilere = hgre.compile
+
class sortdict(sortdict):
-
def preparewrite(self):
"""call this before writes, return self or a copied new object"""
if getattr(self, '_copied', 0):
@@ 15,14 16,17 @@ class sortdict(sortdict):
return self.__class__(self)
return self
-coreconfigitem(b'confman', b'rootpath',
- default=None
-)
+
+coreconfigitem(b'confman', b'rootpath', default=None)
from mercurial import exchange
+
+
def push(local, remote, *args, **kwargs):
return exchange.push(local, remote, *args, **kwargs)
+
+
def pull(local, remote, *args, **kwargs):
return exchange.pull(local, remote, *args, **kwargs)
M hgext3rd/confman/managed.py +97 -98
@@ 1,15 1,17 @@
"This module contains abtractions for managed repositories."
import os
import os.path as osp
+import tarfile
import urllib.parse
-import tarfile
import zipfile
from subprocess import check_output as call
-from mercurial import hg, error, commands, archival, scmutil, util
+from mercurial import archival, commands, error, hg, scmutil, util
from mercurial.utils.urlutil import parseurl
-from .hgcompat import pull as hgpull, push as hgpush
-from .utils import download_file, WrappedRepo
+
+from .hgcompat import pull as hgpull
+from .hgcompat import push as hgpush
+from .utils import WrappedRepo, download_file
class rcbase(object):
@@ 43,7 45,6 @@ class rcbase(object):
class revisioncontext(rcbase):
-
def __init__(self, cset):
self._cset = cset
# be careful with the 'next commit'
@@ 66,8 67,7 @@ class revisioncontext(rcbase):
@property
def parents(self):
- return [revisioncontext(p)
- for p in self._cset.parents()]
+ return [revisioncontext(p) for p in self._cset.parents()]
@property
def phase(self):
@@ 75,33 75,25 @@ class revisioncontext(rcbase):
@property
def tags(self):
- return [
- t.decode('utf-8')
- for t in self._cset.tags()
- ]
+ return [t.decode('utf-8') for t in self._cset.tags()]
@property
def revnum(self):
return self._cset.rev()
def ancestors(self):
- return (revisioncontext(cset)
- for cset in self._cset.ancestors())
+ return (revisioncontext(cset) for cset in self._cset.ancestors())
def descendants(self):
- return (revisioncontext(cset)
- for cset in self._cset.descendants())
+ return (revisioncontext(cset) for cset in self._cset.descendants())
def obsolete(self):
return self._cset.obsolete()
class gitrevisioncontext(rcbase):
-
def _call(self, *args):
- return call(
- ('git',) + args, cwd=self.path
- ).strip().decode('utf-8')
+ return call(('git',) + args, cwd=self.path).strip().decode('utf-8')
def __init__(self, path, hex=None):
self.path = path
@@ 121,8 113,7 @@ class gitrevisioncontext(rcbase):
# git revs (same as we do with hg revs). This is also coherent with the
# "git rev-parse" call below, which gets a long rev.
if self.hex:
- args = ['describe', '--long', '--tags', '--always', '--abbrev=40',
- self.hex]
+ args = ['describe', '--long', '--tags', '--always', '--abbrev=40', self.hex]
try:
out = self._call(*args)
tag, dist, _hex = (['', ''] + out.rsplit('-', 2))[-3:]
@@ 171,17 162,18 @@ def repoclassbyconf(conf, path, hggit=Fa
pulluri = conf['pulluri']
# first check the local repo (if it exists)
- if (osp.isdir(osp.join(path, '.hg'))
- or osp.isdir(osp.join(pulluri, '.hg'))):
+ if osp.isdir(osp.join(path, '.hg')) or osp.isdir(osp.join(pulluri, '.hg')):
return hgrepo
if osp.isdir(osp.join(path, '.git')):
return gitrepo
# then the hg-vs-git-vs-hggit
- if (uri.scheme == 'git' or
- uri.path.endswith('.git') or
- osp.isdir(osp.join(pulluri, '.git'))):
+ if (
+ uri.scheme == 'git'
+ or uri.path.endswith('.git')
+ or osp.isdir(osp.join(pulluri, '.git'))
+ ):
if hggit:
return hgrepo
return gitrepo
@@ 235,8 227,10 @@ class managedrepo(object):
self.conf = conf
self.ui = conf.ui
+
class tgzrepo(managedrepo):
- """ A tarball repository """
+ """A tarball repository"""
+
__slots__ = ('conf', 'ui', 'root')
@classmethod
@@ 247,7 241,9 @@ class tgzrepo(managedrepo):
os.makedirs(dest)
# most of the time, the final folder is archivec
# we would like it to be the final dest
- if set(m.name.split('/', 1)[0] for m in tf.members) == {os.path.basename(dest)}:
+ if set(m.name.split('/', 1)[0] for m in tf.members) == {
+ os.path.basename(dest)
+ }:
dest = os.path.dirname(dest) or '.'
tf.extractall(dest)
@@ 284,7 280,8 @@ class tgzrepo(managedrepo):
class ziprepo(tgzrepo):
- """ A zip repository """
+ """A zip repository"""
+
__slots__ = ('conf', 'ui', 'root')
@classmethod
@@ 297,7 294,8 @@ class ziprepo(tgzrepo):
class gitrepo(managedrepo):
- """ A git repository """
+ """A git repository"""
+
__slots__ = ('conf', 'ui', 'root')
@classmethod
@@ 311,9 309,7 @@ class gitrepo(managedrepo):
def _call(self, *args):
try:
- return call(
- ('git',) + args, cwd=self.root
- ).strip().decode('utf-8')
+ return call(('git',) + args, cwd=self.root).strip().decode('utf-8')
except Exception as exc:
# stdout will show the shit
pass
@@ 330,8 326,9 @@ class gitrepo(managedrepo):
def check_dirty(self, section):
changes = self.changestatus()
if changes:
- self.ui.write('%s repo is unclean, please adjust\n' % section,
- label='confman.dirty')
+ self.ui.write(
+ '%s repo is unclean, please adjust\n' % section, label='confman.dirty'
+ )
return changes
def revsingle(self, rev, skiperror=False):
@@ 352,10 349,9 @@ class gitrepo(managedrepo):
def changestatus(self):
out = self._call('status', '--porcelain')
stat = ''.join(
- sorted(set(
- [l.strip().split()[0].replace('??', 'M')
- for l in out.splitlines()]
- ))
+ sorted(
+ set([l.strip().split()[0].replace('??', 'M') for l in out.splitlines()])
+ )
)
return stat
@@ 367,14 363,13 @@ class gitrepo(managedrepo):
class hgrepo(managedrepo):
- """ A mercurial repository """
+ """A mercurial repository"""
+
__slots__ = ('conf', 'ui', 'repo')
def __init__(self, conf, path):
super(hgrepo, self).__init__(conf, path)
- self.repo = WrappedRepo(
- hg.repository(self.ui, path=path.encode('utf-8'))
- )
+ self.repo = WrappedRepo(hg.repository(self.ui, path=path.encode('utf-8')))
@property
def root(self):
@@ 383,7 378,7 @@ class hgrepo(managedrepo):
def revsingle(self, revexpr, skiperror=False):
"""Return the highest cset of the revset matching the given revision
- expression """
+ expression"""
try:
cset = scmutil.revsingle(self.repo, revexpr.encode('utf-8'))
except:
@@ 394,10 389,8 @@ class hgrepo(managedrepo):
def changestatus(self):
"""Check `modified, added, removed, deleted`
- ignore `unknown, ignored, clean` """
- return ''.join(tag
- for tag, state in zip('MARD', self.repo.status())
- if state)
+ ignore `unknown, ignored, clean`"""
+ return ''.join(tag for tag, state in zip('MARD', self.repo.status()) if state)
def isshared(self):
"""Check if the repository is a shared"""
@@ 409,10 402,11 @@ class hgrepo(managedrepo):
If ``allow_p2`` is False (default) and the current context has
2 parents (a.k.a. merge in progress) the process is aborted.
"""
- cset = self.repo[None] # grab the current context
+ cset = self.repo[None] # grab the current context
if len(cset.parents()) > 1:
- self.ui.write('has two parents (uncommitted merge)\n',
- label='confman.dirty')
+ self.ui.write(
+ 'has two parents (uncommitted merge)\n', label='confman.dirty'
+ )
if not allow_p2:
raise error.Abort(b'bailing out')
return revisioncontext(cset)
@@ 424,7 418,7 @@ class hgrepo(managedrepo):
def workingctx(self):
"""Return the working/current context context of a repository
Will abort if there is more than one parent (it may mean an
- ongoing merge for instance) """
+ ongoing merge for instance)"""
return self.currentctx().parents[0]
@classmethod
@@ 441,23 435,15 @@ class hgrepo(managedrepo):
conf.ui.warn('clone: using %r instead of %r\n' % (newsource, source))
source = newsource
return commands.clone(
- conf.ui,
- source=source.encode('utf-8'),
- dest=dest.encode('utf-8')
+ conf.ui, source=source.encode('utf-8'), dest=dest.encode('utf-8')
)
target = osp.join(sharepath, secconf['layout'])
if not osp.exists(target):
os.makedirs(target)
commands.clone(
- conf.ui,
- source=source.encode('utf-8'),
- dest=target.encode('utf-8')
+ conf.ui, source=source.encode('utf-8'), dest=target.encode('utf-8')
)
- return hg.share(
- conf.ui,
- target.encode('utf-8'),
- dest.encode('utf-8')
- )
+ return hg.share(conf.ui, target.encode('utf-8'), dest.encode('utf-8'))
def pull_repo(self, section, conf):
"""Pull a managed repo from its configuration
@@ 469,15 455,17 @@ class hgrepo(managedrepo):
pathuri = util.expandpath(pathname.encode('utf-8'))
if pathuri == pathname.encode('utf-8'):
pathuri = conf['pulluri'].encode('utf-8')
- ui.warn('%s repo has no `%s` path, using configuration pulluri `%s` instead\n' %
- (section, pathname, pathuri.decode('utf-8')))
+ ui.warn(
+ '%s repo has no `%s` path, using configuration pulluri `%s` instead\n'
+ % (section, pathname, pathuri.decode('utf-8'))
+ )
source, _branches = parseurl(pathuri, None)
newsource = self.conf.rewriteuri(source)
if newsource != source:
- ui.warn('pull: using %r instead of %r\n' % (
- newsource.decode('utf-8'),
- source.decode('utf-8'))
+ ui.warn(
+ 'pull: using %r instead of %r\n'
+ % (newsource.decode('utf-8'), source.decode('utf-8'))
)
source = newsource
@@ 487,9 475,11 @@ class hgrepo(managedrepo):
except error.RepoError:
pulluri = conf['pulluri']
if pathuri == pulluri:
- raise # we already tried
- ui.warn('%s repo cannot be pulled from its local path, using pulluri %s\n' %
- (section, pulluri))
+ raise # we already tried
+ ui.warn(
+ '%s repo cannot be pulled from its local path, using pulluri %s\n'
+ % (section, pulluri)
+ )
source, _branches = parseurl(pulluri.encode(), None)
other = hg.peer(self.repo.ui, self.conf.opts, source)
hgpull(self.repo._repo, other)
@@ 500,8 490,10 @@ class hgrepo(managedrepo):
pathuri = util.expandpath(pathname.encode('utf-8')).decode('utf-8')
if pathuri == pathname:
pathuri = conf['pulluri']
- self.ui.warn('%s repo has no %s path, using configuration pulluri %s instead\n' %
- (section, pathname, pathuri))
+ self.ui.warn(
+ '%s repo has no %s path, using configuration pulluri %s instead\n'
+ % (section, pathname, pathuri)
+ )
track = conf.get('track')
self.ui.write('pushing %s to %s\n' % (track, pathuri))
source, __branches = parseurl(pathuri.encode('utf-8'), None)
@@ 509,7 501,7 @@ class hgrepo(managedrepo):
hgpush(self.repo, other, track.encode('utf-8'))
def unknown_rev(self, rev):
- """Predicate to check if a revision belongs to a repository """
+ """Predicate to check if a revision belongs to a repository"""
try:
self.revsingle(rev)
except (error.RepoLookupError, error.LookupError, error.Abort):
@@ 517,7 509,7 @@ class hgrepo(managedrepo):
return False
def update(self, rev):
- "Update the repository to `rev` "
+ "Update the repository to `rev`"
commands.update(self.ui, self.repo, rev=rev.encode('utf-8'))
def update_or_pull_and_update(self, section, conf, rev):
@@ 538,20 530,20 @@ class hgrepo(managedrepo):
targetrev = targetctx.tag or targetctx.hex
ui.write('updating to %s\n' % rev, label='confman.public-phase')
self.update(rev)
- ui.write('updated to %s/%s from %s/%s\n' %
- (targetrev,
- targetctx.branch,
- currev,
- wctx.branch),
- label='confman.updated')
+ ui.write(
+ 'updated to %s/%s from %s/%s\n'
+ % (targetrev, targetctx.branch, currev, wctx.branch),
+ label='confman.updated',
+ )
return True
def check_dirty(self, section):
- """Check and log the dirtyness of a repository """
+ """Check and log the dirtyness of a repository"""
changes = self.repo[None].dirty(missing=True)
if changes:
- self.ui.write('%s repo is unclean, please adjust\n' % section,
- label='confman.dirty')
+ self.ui.write(
+ '%s repo is unclean, please adjust\n' % section, label='confman.dirty'
+ )
return changes
def archive(self, zippath, prefix, rev, **opts):
@@ 571,14 563,16 @@ class hgrepo(managedrepo):
b'zip',
not opts.get('no_decode'),
matchfn,
- prefix.encode('utf-8')
+ prefix.encode('utf-8'),
)
archival.archivers.update(archivers)
def rewrite_conf(self, conf):
+ from collections import defaultdict
from difflib import unified_diff
- from collections import defaultdict
+
from mercurial.config import config
+
from .utils import _unflatten
# build the nested hgrc entries ([section] key value, key value, ...)
@@ 603,7 597,7 @@ class hgrepo(managedrepo):
if newvalue is not None and newvalue != value:
updated[usection][ukey] = newvalue
entry.pop(ukey, None)
- if not entries[usection]: # now empty
+ if not entries[usection]: # now empty
entries.pop(usection)
# at this point entries contains exclusively *new* entries
@@ 619,20 613,20 @@ class hgrepo(managedrepo):
for line in hgrc:
sline = line.strip()
- if sline.startswith('#'): # comment
+ if sline.startswith('#'): # comment
newhgrc.write(line)
continue
- if updated.get(section): # check updates
+ if updated.get(section): # check updates
parsed = sline.split('=')
if len(parsed) == 2:
key, val = parsed[0].strip(), parsed[1].strip()
newval = updated[section].get(key)
- if newval: # update
+ if newval: # update
newhgrc.write('%s = %s\n' % (key, newval))
continue
- if sline.startswith('['): # new section
+ if sline.startswith('['): # new section
# handle new entries while in the previous section
if entries.get(section):
for key, val in list(entries[section].items()):
@@ 652,8 646,11 @@ class hgrepo(managedrepo):
# show changes
with open(hgrcpath, 'r') as hgrc:
with open(newhgrcpath, 'r') as newhgrc:
- diff = tuple(unified_diff(hgrc.readlines(), newhgrc.readlines(),
- hgrcpath, newhgrcpath))
+ diff = tuple(
+ unified_diff(
+ hgrc.readlines(), newhgrc.readlines(), hgrcpath, newhgrcpath
+ )
+ )
for line in diff:
self.ui.write(line)
@@ 661,7 658,7 @@ class hgrepo(managedrepo):
os.unlink(newhgrcpath)
return ()
- if os.name == 'nt': # atomic rename not a windows thing
+ if os.name == 'nt': # atomic rename not a windows thing
os.unlink(hgrcpath)
os.rename(newhgrcpath, hgrcpath)
return diff
@@ 678,19 675,21 @@ class hgrepo(managedrepo):
class zipit(archival.zipit):
"""Write archive to zip file or stream. Can write uncompressed,
or compressed with deflate."""
+
def __init__(self, dest, mtime, compress=True):
if not isinstance(dest, str):
try:
dest.tell()
except (AttributeError, IOError):
dest = archival.tellable(dest)
- self.z = archival.zipfile.ZipFile(dest, 'a',
- compress and archival.zipfile.ZIP_DEFLATED or
- archival.zipfile.ZIP_STORED
+ self.z = archival.zipfile.ZipFile(
+ dest,
+ 'a',
+ compress and archival.zipfile.ZIP_DEFLATED or archival.zipfile.ZIP_STORED,
)
# Python's zipfile module emits deprecation warnings if we try
# to store files with a date before 1980.
- epoch = 315532800 # calendar.timegm((1980, 1, 1, 0, 0, 0, 1, 1, 0))
+ epoch = 315532800 # calendar.timegm((1980, 1, 1, 0, 0, 0, 1, 1, 0))
if mtime < epoch:
mtime = epoch
self.mtime = mtime
M hgext3rd/confman/meta.py +22 -26
@@ 2,29 2,25 @@
CONFMANENTRIES = ('pulluri', 'layout', 'track')
MANDATORY = ('pulluri', 'layout')
-colortable = {b'confman.nobaseline': b'cyan',
- b'confman.branchaligned': b'magenta',
- b'confman.tagaligned': b'green bold',
- b'confman.csetaligned': b'magenta',
- b'confman.revsetaligned': b'magenta',
- b'confman.unaligned': b'red',
-
- b'confman.nosnap': b'cyan underline',
- b'confman.snapaligned': b'green bold',
- b'confman.snapolder': b'yellow',
- b'confman.snapnewer': b'yellow',
- b'confman.snapparallel': b'yellow',
- b'confman.snapunknown': b'red',
-
- b'confman.draft-phase': b'magenta',
- b'confman.secret-phase': b'red',
- b'confman.public-phase': b'white',
-
- b'confman.clean': b'green',
- b'confman.dirty': b'red',
- b'confman.section': b'green',
-
- b'confman.updated': b'cyan',
-
- b'confman.shared': b'blue'
- }
+colortable = {
+ b'confman.nobaseline': b'cyan',
+ b'confman.branchaligned': b'magenta',
+ b'confman.tagaligned': b'green bold',
+ b'confman.csetaligned': b'magenta',
+ b'confman.revsetaligned': b'magenta',
+ b'confman.unaligned': b'red',
+ b'confman.nosnap': b'cyan underline',
+ b'confman.snapaligned': b'green bold',
+ b'confman.snapolder': b'yellow',
+ b'confman.snapnewer': b'yellow',
+ b'confman.snapparallel': b'yellow',
+ b'confman.snapunknown': b'red',
+ b'confman.draft-phase': b'magenta',
+ b'confman.secret-phase': b'red',
+ b'confman.public-phase': b'white',
+ b'confman.clean': b'green',
+ b'confman.dirty': b'red',
+ b'confman.section': b'green',
+ b'confman.updated': b'cyan',
+ b'confman.shared': b'blue',
+}
M hgext3rd/confman/opts.py +12 -4
@@ 1,9 1,17 @@
INCLUDEOPT = ('I', 'include-conf', [], 'include configuration(s)')
EXCLUDEOPT = ('X', 'exclude-conf', [], 'exclude configuration(s)')
-ROOTPATHOPT = ('', 'root-path', '',
- 'root path for the layouts (default to configuration root)')
-PULLURIOPT = ('p', 'use-hgrc-path', '',
- 'distant repository path name registered into hgrc.paths.*')
+ROOTPATHOPT = (
+ '',
+ 'root-path',
+ '',
+ 'root path for the layouts (default to configuration root)',
+)
+PULLURIOPT = (
+ 'p',
+ 'use-hgrc-path',
+ '',
+ 'distant repository path name registered into hgrc.paths.*',
+)
URIMAPOPT = ('', 'uri-map-file', '', 'specify uri map file')
HTTPSOPT = ('', 'insecure', False, 'work around self bad certificates')
HGGITOPT = ('', 'hggit', None, 'git: operate with hg-git')
M hgext3rd/confman/utils.py +100 -87
@@ 1,17 1,20 @@
"This module contains useful stuff to play with repository specs"
-import os
-import errno
import codecs
-from collections import defaultdict
-import urllib.request, urllib.parse, urllib.error
import contextlib
+import errno
+import os
+import urllib.error
+import urllib.parse
+import urllib.request
+from collections import defaultdict
-from mercurial import util, hg, error
-from mercurial.config import config, _
+from mercurial import error, hg, util
+from mercurial.config import _, config
+
from .hgcompat import compilere
+from .meta import CONFMANENTRIES
-from .meta import CONFMANENTRIES
def ending(line):
"Return the newline character(s) of the line."
@@ 22,15 25,16 @@ def ending(line):
else:
return '\n'
+
# configuration handling
+
def _compilere(pattern):
"Compile regexp (pattern + '$')"
return compilere(pattern + '$')
class WrappedRepo:
-
def __init__(self, repo):
if isinstance(repo, WrappedRepo):
repo = repo._repo
@@ 52,7 56,6 @@ class WrappedRepo:
class WrappedUI:
-
def __init__(self, ui):
if isinstance(ui, WrappedUI):
ui = ui._ui
@@ 62,43 65,25 @@ class WrappedUI:
if label:
label = label.encode('utf-8')
return meth(
- *(elt.encode('utf-8')
- if isinstance(elt, str) else elt
- for elt in a),
+ *(elt.encode('utf-8') if isinstance(elt, str) else elt for elt in a),
label=label,
**k
)
def write(self, *a, label=b'', **k):
- return self._output(
- self._ui.write,
- *a, label=label, **k
- )
+ return self._output(self._ui.write, *a, label=label, **k)
def status(self, *a, label=b'', **k):
- return self._output(
- self._ui.status,
- *a, label=label, **k
- )
+ return self._output(self._ui.status, *a, label=label, **k)
def warn(self, *a, label=b'', **k):
- return self._output(
- self._ui.warn,
- *a, label=label, **k
- )
+ return self._output(self._ui.warn, *a, label=label, **k)
def error(self, *a, label=b'', **k):
- return self._output(
- self._ui.error,
- *a, label=label, **k
- )
+ return self._output(self._ui.error, *a, label=label, **k)
def configpath(self, *args, **kw):
- args = (
- elt.encode('utf-8')
- if isinstance(elt, str) else elt
- for elt in args
- )
+ args = (elt.encode('utf-8') if isinstance(elt, str) else elt for elt in args)
path = self._ui.configpath(*args, **kw)
if path is not None:
return path.decode('utf-8')
@@ 132,20 117,24 @@ class sectionfilter(object):
self.whitelist = parent.whitelist
self.blacklist = parent.blacklist
if regexp:
- self.rewhitelist = (self.rewhitelist +
- tuple(_compilere(exp) for exp in morewhite))
- self.reblacklist = (self.reblacklist +
- tuple(_compilere(exp) for exp in moreblack))
+ self.rewhitelist = self.rewhitelist + tuple(
+ _compilere(exp) for exp in morewhite
+ )
+ self.reblacklist = self.reblacklist + tuple(
+ _compilere(exp) for exp in moreblack
+ )
else:
self.whitelist = self.whitelist + morewhite
self.blacklist = self.blacklist + moreblack
def __call__(self, section):
- if (section in self.blacklist or
- any(re.match(section) for re in self.reblacklist)):
+ if section in self.blacklist or any(
+ re.match(section) for re in self.reblacklist
+ ):
return False
- if ((self.whitelist and section not in self.whitelist) or
- (self.rewhitelist and not any(re.match(section) for re in self.rewhitelist))):
+ if (self.whitelist and section not in self.whitelist) or (
+ self.rewhitelist and not any(re.match(section) for re in self.rewhitelist)
+ ):
return False
return True
@@ 202,9 191,17 @@ class oconfig(object):
hgrc.write('%s = %s\n' % (k, v))
hgrc.write('\n')
- def parse(self, src, data, sections=None, remap=None, include=None,
- # PATCH: level and filtering
- level=0, section_filter=None):
+ def parse(
+ self,
+ src,
+ data,
+ sections=None,
+ remap=None,
+ include=None,
+ # PATCH: level and filtering
+ level=0,
+ section_filter=None,
+ ):
sectionre = compilere(r'\[([^\[]+)\]')
itemre = compilere(r'([^=\s][^=]*?)\s*=\s*(.*\S|)')
# PATCH
@@ 250,9 247,10 @@ class oconfig(object):
include(inc, remap=remap, sections=sections)
except IOError as inst:
if inst.errno != errno.ENOENT:
- raise error.ParseError(_("cannot include %s (%s)")
- % (inc, inst.strerror),
- "%s:%s" % (src, line))
+ raise error.ParseError(
+ _("cannot include %s (%s)") % (inc, inst.strerror),
+ "%s:%s" % (src, line),
+ )
continue
if emptyre.match(l):
continue
@@ 288,19 286,27 @@ class oconfig(object):
morewhite = tuple(m.group(4).split())
elif m.group(2) == '.blacklist':
moreblack += tuple(m.group(4).split())
- _section_filter = sectionfilter(regexp=bool(m.group(3)),
- parent=section_filter,
- morewhite=morewhite,
- moreblack=moreblack)
+ _section_filter = sectionfilter(
+ regexp=bool(m.group(3)),
+ parent=section_filter,
+ morewhite=morewhite,
+ moreblack=moreblack,
+ )
try:
- include(inc, remap=remap, sections=sections, level=level+1,
- section_filter=_section_filter)
+ include(
+ inc,
+ remap=remap,
+ sections=sections,
+ level=level + 1,
+ section_filter=_section_filter,
+ )
except IOError as inst:
if inst.errno != errno.ENOENT:
- raise error.ParseError(_("cannot expand %s (%s)")
- % (inc, inst.strerror),
- "%s:%s" % (src, line))
+ raise error.ParseError(
+ _("cannot expand %s (%s)") % (inc, inst.strerror),
+ "%s:%s" % (src, line),
+ )
continue
# /PATCH
m = itemre.match(l)
@@ 322,8 328,7 @@ class oconfig(object):
continue
raise error.ParseError(
- l.rstrip().encode('utf-8'),
- ("%s:%s" % (src, line)).encode('utf-8')
+ l.rstrip().encode('utf-8'), ("%s:%s" % (src, line)).encode('utf-8')
)
def parse_guestrepo(self, dirpath, level=0, section_filter=None):
@@ 341,7 346,7 @@ class oconfig(object):
self.set(
section.decode('utf-8'),
'pulluri',
- mappingconf[b''][section][0].decode('utf-8')
+ mappingconf[b''][section][0].decode('utf-8'),
)
self.confman.sectionlevels[section.decode('utf-8')].add(level)
guestpath = os.path.join(dirpath, '.hgguestrepo')
@@ 350,16 355,8 @@ class oconfig(object):
for layout in guestconf[b'']:
section, cset = guestconf[b''][layout][0].split(None, 1)
if section_filter(section):
- self.set(
- section.decode('utf-8'),
- 'layout',
- layout.decode('utf-8')
- )
- self.set(
- section.decode('utf-8'),
- 'track',
- cset.decode('utf-8')
- )
+ self.set(section.decode('utf-8'), 'layout', layout.decode('utf-8'))
+ self.set(section.decode('utf-8'), 'track', cset.decode('utf-8'))
def read(self, path, fp=None, sections=None, remap=None, **kwargs):
if os.path.exists(path):
@@ 377,9 374,10 @@ def upwarditer(path):
while path:
yield path
path = os.path.dirname(path)
- if path in ('', '/'): # root, depending on linux/win32
+ if path in ('', '/'): # root, depending on linux/win32
return
+
def findrootpath(ui, conffilename, startpath):
"Find `conffilename` by changing directories upward"
for iterations, repourl in enumerate(upwarditer(startpath)):
@@ 387,8 385,10 @@ def findrootpath(ui, conffilename, start
if os.path.exists(confpath):
if iterations:
if not ui.quiet:
- ui.write('found configuration repo at %s\n' % repourl,
- label='confman.updated')
+ ui.write(
+ 'found configuration repo at %s\n' % repourl,
+ label='confman.updated',
+ )
yield repourl
raise StopIteration
else:
@@ 401,8 401,11 @@ def readconf(ui, repo, args, opts):
# prevent cyclic imports
from . import gr
from .configuration import configurationmanager
- for cmrootpath, grrootpath in zip(findrootpath(ui, '.hgconf', repo.root),
- findrootpath(ui, '.hgguestrepo', repo.root)):
+
+ for cmrootpath, grrootpath in zip(
+ findrootpath(ui, '.hgconf', repo.root),
+ findrootpath(ui, '.hgguestrepo', repo.root),
+ ):
if cmrootpath:
confman = configurationmanager(ui, cmrootpath, args, opts)
break
@@ 411,16 414,15 @@ def readconf(ui, repo, args, opts):
break
else:
raise error.Abort(
- b'cannot find an .hgconf file in the path and '
- b'parents up to the root',
- hint=b'see hg help confman'
+ b'cannot find an .hgconf file in the path and ' b'parents up to the root',
+ hint=b'see hg help confman',
)
- return confman, WrappedRepo(
- hg.repository(ui, confman.rootpath.encode('utf-8'))
- )
+ return confman, WrappedRepo(hg.repository(ui, confman.rootpath.encode('utf-8')))
+
# dictionnaries operations
+
def _unflatten(flattened, skipkeys=CONFMANENTRIES, failed=None):
"""Build nested dictionaries from a flattened one, e.g
hgrc.path.default-push -> {'hgrc': {'path': {'defaul-push': ...}}}
@@ 439,8 441,10 @@ def _unflatten(flattened, skipkeys=CONFM
nested[toplevel][newsection][newkey] = value
return nested
+
# download utility
+
@contextlib.contextmanager
def download_file(source):
"""Download file at ``source``. This function manage file:// scheme"""
@@ 449,7 453,10 @@ def download_file(source):
with open(os.path.join(*source[7:].split('/')), 'rb') as fp:
yield fp
else:
- import requests, tempfile
+ import tempfile
+
+ import requests
+
req = requests.get(source, stream=True)
with tempfile.TemporaryFile() as fp:
for chunk in req.iter_content(chunk_size=4096):
@@ 461,22 468,28 @@ def download_file(source):
# register encoding error handlers
+
def _treegraph_unicode_encode_handler(error):
"""Unicode error handler for tree graph characters. Shall be given to
codecs.register_error."""
- obj = error.object[error.start:error.end + 1]
- obj = obj.replace('\N{BOX DRAWINGS LIGHT VERTICAL}', '|') # │
- obj = obj.replace('\N{BOX DRAWINGS LIGHT VERTICAL AND RIGHT}', '|') # ├
- obj = obj.replace('\N{BOX DRAWINGS LIGHT UP AND RIGHT}', '`') # └
- obj = obj.replace('\N{RIGHTWARDS ARROW}', '-') # →
+ obj = error.object[error.start : error.end + 1]
+ obj = obj.replace('\N{BOX DRAWINGS LIGHT VERTICAL}', '|') # │
+ obj = obj.replace('\N{BOX DRAWINGS LIGHT VERTICAL AND RIGHT}', '|') # ├
+ obj = obj.replace('\N{BOX DRAWINGS LIGHT UP AND RIGHT}', '`') # └
+ obj = obj.replace('\N{RIGHTWARDS ARROW}', '-') # →
return obj, error.end + 1
+
+
codecs.register_error('treegraph', _treegraph_unicode_encode_handler)
# a 'confman' encoding error handler
+
def _confman_unicode_encode_handler(error):
- obj = error.object[error.start:error.end + 1]
+ obj = error.object[error.start : error.end + 1]
obj = obj.replace('\N{CHECK MARK}', 'ok')
obj = obj.replace('\N{MARRIAGE SYMBOL}', '[shared]')
return obj, error.end
+
+
codecs.register_error('confman', _confman_unicode_encode_handler)
A => pyproject.toml +6 -0
@@ 0,0 1,6 @@
+[tool.isort]
+profile = "black"
+
+[tool.black]
+skip-string-normalization = true
+extend-exclude = "run-tests.py"
M setup.py +2 -3
@@ 7,7 7,6 @@ setup(
url='https://hg.sr.ht/~auc/confman',
author=u'Aurélien Campéas',
author_email='aurelien.campeas@pythonian.fr',
-
license='GPLv2+',
keywords='hg mercurial',
packages=['hgext3rd', 'hgext3rd.confman'],
@@ 19,6 18,6 @@ setup(
'Operating System :: OS Independent',
'Programming Language :: Python :: 3',
'Topic :: Software Development :: Version Control',
- 'Topic :: Software Development :: Version Control :: Mercurial'
- ]
+ 'Topic :: Software Development :: Version Control :: Mercurial',
+ ],
)