Extract makedate from util.py to utils/dateutil.py
Details
Details
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
- Lint Skipped 
- Unit
- Unit Tests Skipped 
| lothiraldan | 
| hg-reviewers | 
Extract makedate from util.py to utils/dateutil.py
| Lint Skipped | 
| Unit Tests Skipped | 
| Path | Packages | |||
|---|---|---|---|---|
| M | contrib/synthrepo.py (4 lines) | |||
| M | hgext/convert/common.py (2 lines) | |||
| M | hgext/journal.py (3 lines) | |||
| M | hgext/mq.py (3 lines) | |||
| M | hgext/patchbomb.py (3 lines) | |||
| M | hgext/shelve.py (4 lines) | |||
| M | mercurial/changelog.py (3 lines) | |||
| M | mercurial/commands.py (3 lines) | |||
| M | mercurial/context.py (7 lines) | |||
| M | mercurial/hgweb/hgwebdir_mod.py (5 lines) | |||
| M | mercurial/obsolete.py (5 lines) | |||
| M | mercurial/templater.py (3 lines) | |||
| M | mercurial/util.py (29 lines) | |||
| M | mercurial/utils/dateutil.py (22 lines) | |||
| M | tests/test-journal.t (3 lines) | 
| Status | Author | Revision | |
|---|---|---|---|
| Abandoned | durin42 | D2056 util: extract matchdate  | |
| Abandoned | durin42 | D2055 util: extract parsedate  | |
| Abandoned | durin42 | D2054 util: extract strdate  | |
| Abandoned | durin42 | ||
| Abandoned | durin42 | D2052 util: extract shortdate  | |
| Abandoned | durin42 | D2051 util: extract datestr  | |
| Abandoned | durin42 | D2050 util: extract makedate  | |
| Abandoned | durin42 | ||
| Abandoned | lothiraldan | ||
| Abandoned | lothiraldan | ||
| Abandoned | durin42 | 
| ) | ) | ||||
| from mercurial import ( | from mercurial import ( | ||||
| context, | context, | ||||
| error, | error, | ||||
| hg, | hg, | ||||
| patch, | patch, | ||||
| registrar, | registrar, | ||||
| scmutil, | scmutil, | ||||
| util, | |||||
| ) | ) | ||||
| from mercurial.utils import dateutil | |||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
| # be specifying the version(s) of Mercurial they are tested with, or | # be specifying the version(s) of Mercurial they are tested with, or | ||||
| # leave the attribute unspecified. | # leave the attribute unspecified. | ||||
| testedwith = 'ships-with-hg-core' | testedwith = 'ships-with-hg-core' | ||||
| cmdtable = {} | cmdtable = {} | ||||
| def filectxfn(repo, memctx, path): | def filectxfn(repo, memctx, path): | ||||
| return context.memfilectx(repo, memctx, path, files[path]) | return context.memfilectx(repo, memctx, path, files[path]) | ||||
| ui.progress(_synthesizing, None) | ui.progress(_synthesizing, None) | ||||
| message = 'synthesized wide repo with %d files' % (len(files),) | message = 'synthesized wide repo with %d files' % (len(files),) | ||||
| mc = context.memctx(repo, [pctx.node(), nullid], message, | mc = context.memctx(repo, [pctx.node(), nullid], message, | ||||
| files.iterkeys(), filectxfn, ui.username(), | files.iterkeys(), filectxfn, ui.username(), | ||||
| '%d %d' % util.makedate()) | '%d %d' % dateutil.makedate()) | ||||
| initnode = mc.commit() | initnode = mc.commit() | ||||
| if ui.debugflag: | if ui.debugflag: | ||||
| hexfn = hex | hexfn = hex | ||||
| else: | else: | ||||
| hexfn = short | hexfn = short | ||||
| ui.status(_('added commit %s with %d files\n') | ui.status(_('added commit %s with %d files\n') | ||||
| % (hexfn(initnode), len(files))) | % (hexfn(initnode), len(files))) | ||||
| super(mapfile, self).__setitem__(key, value) | super(mapfile, self).__setitem__(key, value) | ||||
| def close(self): | def close(self): | ||||
| if self.fp: | if self.fp: | ||||
| self.fp.close() | self.fp.close() | ||||
| self.fp = None | self.fp = None | ||||
| def makedatetimestamp(t): | def makedatetimestamp(t): | ||||
| """Like util.makedate() but for time t instead of current time""" | """Like dateutil.makedate() but for time t instead of current time""" | ||||
| delta = (datetime.datetime.utcfromtimestamp(t) - | delta = (datetime.datetime.utcfromtimestamp(t) - | ||||
| datetime.datetime.fromtimestamp(t)) | datetime.datetime.fromtimestamp(t)) | ||||
| tz = delta.days * 86400 + delta.seconds | tz = delta.days * 86400 + delta.seconds | ||||
| return t, tz | return t, tz | ||||
| hg, | hg, | ||||
| localrepo, | localrepo, | ||||
| lock, | lock, | ||||
| node, | node, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from mercurial.utils import dateutil | |||||
| from . import share | from . import share | ||||
| cmdtable = {} | cmdtable = {} | ||||
| command = registrar.command(cmdtable) | command = registrar.command(cmdtable) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
| """ | """ | ||||
| if not isinstance(oldhashes, list): | if not isinstance(oldhashes, list): | ||||
| oldhashes = [oldhashes] | oldhashes = [oldhashes] | ||||
| if not isinstance(newhashes, list): | if not isinstance(newhashes, list): | ||||
| newhashes = [newhashes] | newhashes = [newhashes] | ||||
| entry = journalentry( | entry = journalentry( | ||||
| util.makedate(), self.user, self.command, namespace, name, | dateutil.makedate(), self.user, self.command, namespace, name, | ||||
| oldhashes, newhashes) | oldhashes, newhashes) | ||||
| vfs = self.vfs | vfs = self.vfs | ||||
| if self.sharedvfs is not None: | if self.sharedvfs is not None: | ||||
| # write to the shared repository if this feature is being | # write to the shared repository if this feature is being | ||||
| # shared between working copies. | # shared between working copies. | ||||
| if sharednamespaces.get(namespace) in self.sharedfeatures: | if sharednamespaces.get(namespace) in self.sharedfeatures: | ||||
| vfs = self.sharedvfs | vfs = self.sharedvfs | ||||
| registrar, | registrar, | ||||
| revsetlang, | revsetlang, | ||||
| scmutil, | scmutil, | ||||
| smartset, | smartset, | ||||
| subrepo, | subrepo, | ||||
| util, | util, | ||||
| vfs as vfsmod, | vfs as vfsmod, | ||||
| ) | ) | ||||
| from mercurial.utils import dateutil | |||||
| release = lockmod.release | release = lockmod.release | ||||
| seriesopts = [('s', 'summary', None, _('print first line of patch header'))] | seriesopts = [('s', 'summary', None, _('print first line of patch header'))] | ||||
| cmdtable = {} | cmdtable = {} | ||||
| command = registrar.command(cmdtable) | command = registrar.command(cmdtable) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should | ||||
| idx = q.series.index(q.applied[-2].name) | idx = q.series.index(q.applied[-2].name) | ||||
| q.qseries(repo, start=idx, length=1, status='A', | q.qseries(repo, start=idx, length=1, status='A', | ||||
| summary=opts.get(r'summary')) | summary=opts.get(r'summary')) | ||||
| def setupheaderopts(ui, opts): | def setupheaderopts(ui, opts): | ||||
| if not opts.get('user') and opts.get('currentuser'): | if not opts.get('user') and opts.get('currentuser'): | ||||
| opts['user'] = ui.username() | opts['user'] = ui.username() | ||||
| if not opts.get('date') and opts.get('currentdate'): | if not opts.get('date') and opts.get('currentdate'): | ||||
| opts['date'] = "%d %d" % util.makedate() | opts['date'] = "%d %d" % dateutil.makedate() | ||||
| @command("^qnew", | @command("^qnew", | ||||
| [('e', 'edit', None, _('invoke editor on commit messages')), | [('e', 'edit', None, _('invoke editor on commit messages')), | ||||
| ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')), | ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')), | ||||
| ('g', 'git', None, _('use git extended diff format')), | ('g', 'git', None, _('use git extended diff format')), | ||||
| ('U', 'currentuser', None, _('add "From: <current user>" to patch')), | ('U', 'currentuser', None, _('add "From: <current user>" to patch')), | ||||
| ('u', 'user', '', | ('u', 'user', '', | ||||
| _('add "From: <USER>" to patch'), _('USER')), | _('add "From: <USER>" to patch'), _('USER')), | ||||
| patch, | patch, | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| repair, | repair, | ||||
| scmutil, | scmutil, | ||||
| templater, | templater, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from mercurial.utils import dateutil | |||||
| stringio = util.stringio | stringio = util.stringio | ||||
| cmdtable = {} | cmdtable = {} | ||||
| command = registrar.command(cmdtable) | command = registrar.command(cmdtable) | ||||
| configtable = {} | configtable = {} | ||||
| configitem = registrar.configitem(configtable) | configitem = registrar.configitem(configtable) | ||||
| for h in repo.set('heads(%ld)', missing)) | for h in repo.set('heads(%ld)', missing)) | ||||
| hint = _("use 'hg push %s %s'") % (publicurl, revhint) | hint = _("use 'hg push %s %s'") % (publicurl, revhint) | ||||
| raise error.Abort(msg, hint=hint) | raise error.Abort(msg, hint=hint) | ||||
| # start | # start | ||||
| if date: | if date: | ||||
| start_time = util.parsedate(date) | start_time = util.parsedate(date) | ||||
| else: | else: | ||||
| start_time = util.makedate() | start_time = dateutil.makedate() | ||||
| def genmsgid(id): | def genmsgid(id): | ||||
| return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn()) | return '<%s.%s@%s>' % (id[:20], int(start_time[0]), socket.getfqdn()) | ||||
| # deprecated config: patchbomb.from | # deprecated config: patchbomb.from | ||||
| sender = (opts.get('from') or ui.config('email', 'from') or | sender = (opts.get('from') or ui.config('email', 'from') or | ||||
| ui.config('patchbomb', 'from') or | ui.config('patchbomb', 'from') or | ||||
| prompt(ui, 'From', ui.username())) | prompt(ui, 'From', ui.username())) | ||||
| pycompat, | pycompat, | ||||
| registrar, | registrar, | ||||
| repair, | repair, | ||||
| scmutil, | scmutil, | ||||
| templatefilters, | templatefilters, | ||||
| util, | util, | ||||
| vfs as vfsmod, | vfs as vfsmod, | ||||
| ) | ) | ||||
| from mercurial.utils import dateutil | |||||
| from . import ( | from . import ( | ||||
| rebase, | rebase, | ||||
| ) | ) | ||||
| cmdtable = {} | cmdtable = {} | ||||
| command = registrar.command(cmdtable) | command = registrar.command(cmdtable) | ||||
| # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for | ||||
| continue | continue | ||||
| ui.write(sname, label=namelabel) | ui.write(sname, label=namelabel) | ||||
| namelabel = 'shelve.name' | namelabel = 'shelve.name' | ||||
| if ui.quiet: | if ui.quiet: | ||||
| ui.write('\n') | ui.write('\n') | ||||
| continue | continue | ||||
| ui.write(' ' * (16 - len(sname))) | ui.write(' ' * (16 - len(sname))) | ||||
| used = 16 | used = 16 | ||||
| age = '(%s)' % templatefilters.age(util.makedate(mtime), abbrev=True) | date = dateutil.makedate(mtime) | ||||
| age = '(%s)' % templatefilters.age(date, abbrev=True) | |||||
| ui.write(age, label='shelve.age') | ui.write(age, label='shelve.age') | ||||
| ui.write(' ' * (12 - len(age))) | ui.write(' ' * (12 - len(age))) | ||||
| used += 12 | used += 12 | ||||
| with open(name + '.' + patchextension, 'rb') as fp: | with open(name + '.' + patchextension, 'rb') as fp: | ||||
| while True: | while True: | ||||
| line = fp.readline() | line = fp.readline() | ||||
| if not line: | if not line: | ||||
| break | break | ||||
| ) | ) | ||||
| from . import ( | from . import ( | ||||
| encoding, | encoding, | ||||
| error, | error, | ||||
| revlog, | revlog, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from .utils import dateutil | |||||
| _defaultextra = {'branch': 'default'} | _defaultextra = {'branch': 'default'} | ||||
| def _string_escape(text): | def _string_escape(text): | ||||
| """ | """ | ||||
| >>> from .pycompat import bytechr as chr | >>> from .pycompat import bytechr as chr | ||||
| >>> d = {b'nl': chr(10), b'bs': chr(92), b'cr': chr(13), b'nul': chr(0)} | >>> d = {b'nl': chr(10), b'bs': chr(92), b'cr': chr(13), b'nul': chr(0)} | ||||
| >>> s = b"ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d | >>> s = b"ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d | ||||
| raise error.RevlogError(_("username %s contains a newline") | raise error.RevlogError(_("username %s contains a newline") | ||||
| % repr(user)) | % repr(user)) | ||||
| desc = stripdesc(desc) | desc = stripdesc(desc) | ||||
| if date: | if date: | ||||
| parseddate = "%d %d" % util.parsedate(date) | parseddate = "%d %d" % util.parsedate(date) | ||||
| else: | else: | ||||
| parseddate = "%d %d" % util.makedate() | parseddate = "%d %d" % dateutil.makedate() | ||||
| if extra: | if extra: | ||||
| branch = extra.get("branch") | branch = extra.get("branch") | ||||
| if branch in ("default", ""): | if branch in ("default", ""): | ||||
| del extra["branch"] | del extra["branch"] | ||||
| elif branch in (".", "null", "tip"): | elif branch in (".", "null", "tip"): | ||||
| raise error.RevlogError(_('the name \'%s\' is reserved') | raise error.RevlogError(_('the name \'%s\' is reserved') | ||||
| % branch) | % branch) | ||||
| if extra: | if extra: | ||||
| server, | server, | ||||
| sshserver, | sshserver, | ||||
| streamclone, | streamclone, | ||||
| tags as tagsmod, | tags as tagsmod, | ||||
| templatekw, | templatekw, | ||||
| ui as uimod, | ui as uimod, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from .utils import dateutil | |||||
| release = lockmod.release | release = lockmod.release | ||||
| table = {} | table = {} | ||||
| table.update(debugcommandsmod.command._table) | table.update(debugcommandsmod.command._table) | ||||
| command = registrar.command(table) | command = registrar.command(table) | ||||
| readonly = registrar.command.readonly | readonly = registrar.command.readonly | ||||
| 'revision ordering!\n')) | 'revision ordering!\n')) | ||||
| revs = list(revs) | revs = list(revs) | ||||
| revs.extend(opts.get('rev')) | revs.extend(opts.get('rev')) | ||||
| if not opts.get('user') and opts.get('currentuser'): | if not opts.get('user') and opts.get('currentuser'): | ||||
| opts['user'] = ui.username() | opts['user'] = ui.username() | ||||
| if not opts.get('date') and opts.get('currentdate'): | if not opts.get('date') and opts.get('currentdate'): | ||||
| opts['date'] = "%d %d" % util.makedate() | opts['date'] = "%d %d" % dateutil.makedate() | ||||
| editor = cmdutil.getcommiteditor(editform='graft', | editor = cmdutil.getcommiteditor(editform='graft', | ||||
| **pycompat.strkwargs(opts)) | **pycompat.strkwargs(opts)) | ||||
| cont = False | cont = False | ||||
| if opts.get('continue'): | if opts.get('continue'): | ||||
| cont = True | cont = True | ||||
| if revs: | if revs: | ||||
| pycompat, | pycompat, | ||||
| repoview, | repoview, | ||||
| revlog, | revlog, | ||||
| scmutil, | scmutil, | ||||
| sparse, | sparse, | ||||
| subrepo, | subrepo, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from .utils import dateutil | |||||
| propertycache = util.propertycache | propertycache = util.propertycache | ||||
| nonascii = re.compile(r'[^\x21-\x7f]').search | nonascii = re.compile(r'[^\x21-\x7f]').search | ||||
| class basectx(object): | class basectx(object): | ||||
| """A basectx object represents the common logic for its children: | """A basectx object represents the common logic for its children: | ||||
| changectx: read-only context that is already present in the repo, | changectx: read-only context that is already present in the repo, | ||||
| def _user(self): | def _user(self): | ||||
| return self._repo.ui.username() | return self._repo.ui.username() | ||||
| @propertycache | @propertycache | ||||
| def _date(self): | def _date(self): | ||||
| ui = self._repo.ui | ui = self._repo.ui | ||||
| date = ui.configdate('devel', 'default-date') | date = ui.configdate('devel', 'default-date') | ||||
| if date is None: | if date is None: | ||||
| date = util.makedate() | date = dateutil.makedate() | ||||
| return date | return date | ||||
| def subrev(self, subpath): | def subrev(self, subpath): | ||||
| return None | return None | ||||
| def manifestnode(self): | def manifestnode(self): | ||||
| return None | return None | ||||
| def user(self): | def user(self): | ||||
| "entries: %s)" | "entries: %s)" | ||||
| % (path, path, self.p1(), len(matches), | % (path, path, self.p1(), len(matches), | ||||
| ', '.join(matches.keys()))) | ', '.join(matches.keys()))) | ||||
| def write(self, path, data, flags='', **kwargs): | def write(self, path, data, flags='', **kwargs): | ||||
| if data is None: | if data is None: | ||||
| raise error.ProgrammingError("data must be non-None") | raise error.ProgrammingError("data must be non-None") | ||||
| self._auditconflicts(path) | self._auditconflicts(path) | ||||
| self._markdirty(path, exists=True, data=data, date=util.makedate(), | self._markdirty(path, exists=True, data=data, date=dateutil.makedate(), | ||||
| flags=flags) | flags=flags) | ||||
| def setflags(self, path, l, x): | def setflags(self, path, l, x): | ||||
| self._markdirty(path, exists=True, date=util.makedate(), | self._markdirty(path, exists=True, date=dateutil.makedate(), | ||||
| flags=(l and 'l' or '') + (x and 'x' or '')) | flags=(l and 'l' or '') + (x and 'x' or '')) | ||||
| def remove(self, path): | def remove(self, path): | ||||
| self._markdirty(path, exists=False) | self._markdirty(path, exists=False) | ||||
| def exists(self, path): | def exists(self, path): | ||||
| """exists behaves like `lexists`, but needs to follow symlinks and | """exists behaves like `lexists`, but needs to follow symlinks and | ||||
| return False if they are broken. | return False if they are broken. | ||||
| hg, | hg, | ||||
| profiling, | profiling, | ||||
| pycompat, | pycompat, | ||||
| scmutil, | scmutil, | ||||
| templater, | templater, | ||||
| ui as uimod, | ui as uimod, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from ..utils import dateutil | |||||
| from . import ( | from . import ( | ||||
| hgweb_mod, | hgweb_mod, | ||||
| webutil, | webutil, | ||||
| wsgicgi, | wsgicgi, | ||||
| ) | ) | ||||
| def cleannames(items): | def cleannames(items): | ||||
| if req.env['SCRIPT_NAME']: | if req.env['SCRIPT_NAME']: | ||||
| parts.insert(0, req.env['SCRIPT_NAME']) | parts.insert(0, req.env['SCRIPT_NAME']) | ||||
| url = re.sub(r'/+', '/', '/'.join(parts) + '/') | url = re.sub(r'/+', '/', '/'.join(parts) + '/') | ||||
| # show either a directory entry or a repository | # show either a directory entry or a repository | ||||
| if directory: | if directory: | ||||
| # get the directory's time information | # get the directory's time information | ||||
| try: | try: | ||||
| d = (get_mtime(path), util.makedate()[1]) | d = (get_mtime(path), dateutil.makedate()[1]) | ||||
| except OSError: | except OSError: | ||||
| continue | continue | ||||
| # add '/' to the name to make it obvious that | # add '/' to the name to make it obvious that | ||||
| # the entry is a directory, not a regular repository | # the entry is a directory, not a regular repository | ||||
| row = {'contact': "", | row = {'contact': "", | ||||
| 'contact_sort': "", | 'contact_sort': "", | ||||
| 'name': name + '/', | 'name': name + '/', | ||||
| r = hg.repository(self.ui, path) | r = hg.repository(self.ui, path) | ||||
| except IOError: | except IOError: | ||||
| u.warn(_('error accessing repository at %s\n') % path) | u.warn(_('error accessing repository at %s\n') % path) | ||||
| continue | continue | ||||
| except error.RepoError: | except error.RepoError: | ||||
| u.warn(_('error accessing repository at %s\n') % path) | u.warn(_('error accessing repository at %s\n') % path) | ||||
| continue | continue | ||||
| try: | try: | ||||
| d = (get_mtime(r.spath), util.makedate()[1]) | d = (get_mtime(r.spath), dateutil.makedate()[1]) | ||||
| except OSError: | except OSError: | ||||
| continue | continue | ||||
| contact = get_contact(get) | contact = get_contact(get) | ||||
| description = get("web", "description") | description = get("web", "description") | ||||
| seenrepos.add(name) | seenrepos.add(name) | ||||
| name = get("web", "name", name) | name = get("web", "name", name) | ||||
| row = {'contact': contact or "unknown", | row = {'contact': contact or "unknown", | ||||
| from . import ( | from . import ( | ||||
| error, | error, | ||||
| node, | node, | ||||
| obsutil, | obsutil, | ||||
| phases, | phases, | ||||
| policy, | policy, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from .utils import dateutil | |||||
| parsers = policy.importmod(r'parsers') | parsers = policy.importmod(r'parsers') | ||||
| _pack = struct.pack | _pack = struct.pack | ||||
| _unpack = struct.unpack | _unpack = struct.unpack | ||||
| _calcsize = struct.calcsize | _calcsize = struct.calcsize | ||||
| propertycache = util.propertycache | propertycache = util.propertycache | ||||
| metadata = {} | metadata = {} | ||||
| if date is None: | if date is None: | ||||
| if 'date' in metadata: | if 'date' in metadata: | ||||
| # as a courtesy for out-of-tree extensions | # as a courtesy for out-of-tree extensions | ||||
| date = util.parsedate(metadata.pop('date')) | date = util.parsedate(metadata.pop('date')) | ||||
| elif ui is not None: | elif ui is not None: | ||||
| date = ui.configdate('devel', 'default-date') | date = ui.configdate('devel', 'default-date') | ||||
| if date is None: | if date is None: | ||||
| date = util.makedate() | date = dateutil.makedate() | ||||
| else: | else: | ||||
| date = util.makedate() | date = dateutil.makedate() | ||||
| if len(prec) != 20: | if len(prec) != 20: | ||||
| raise ValueError(prec) | raise ValueError(prec) | ||||
| for succ in succs: | for succ in succs: | ||||
| if len(succ) != 20: | if len(succ) != 20: | ||||
| raise ValueError(succ) | raise ValueError(succ) | ||||
| if prec in succs: | if prec in succs: | ||||
| raise ValueError(_('in-marker cycle with %s') % node.hex(prec)) | raise ValueError(_('in-marker cycle with %s') % node.hex(prec)) | ||||
| registrar, | registrar, | ||||
| revset as revsetmod, | revset as revsetmod, | ||||
| revsetlang, | revsetlang, | ||||
| scmutil, | scmutil, | ||||
| templatefilters, | templatefilters, | ||||
| templatekw, | templatekw, | ||||
| util, | util, | ||||
| ) | ) | ||||
| from .utils import dateutil | |||||
| # template parsing | # template parsing | ||||
| elements = { | elements = { | ||||
| # token-type: binding-strength, primary, prefix, infix, suffix | # token-type: binding-strength, primary, prefix, infix, suffix | ||||
| "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None), | "(": (20, None, ("group", 1, ")"), ("func", 1, ")"), None), | ||||
| ".": (18, None, None, (".", 18), None), | ".": (18, None, None, (".", 18), None), | ||||
| "%": (15, None, None, ("%", 15), None), | "%": (15, None, None, ("%", 15), None), | ||||
| tzoffset = None | tzoffset = None | ||||
| if tzoffset is None: | if tzoffset is None: | ||||
| try: | try: | ||||
| tzoffset = int(tz) | tzoffset = int(tz) | ||||
| except (TypeError, ValueError): | except (TypeError, ValueError): | ||||
| # i18n: "localdate" is a keyword | # i18n: "localdate" is a keyword | ||||
| raise error.ParseError(_("localdate expects a timezone")) | raise error.ParseError(_("localdate expects a timezone")) | ||||
| else: | else: | ||||
| tzoffset = util.makedate()[1] | tzoffset = dateutil.makedate()[1] | ||||
| return (date[0], tzoffset) | return (date[0], tzoffset) | ||||
| @templatefunc('max(iterable)') | @templatefunc('max(iterable)') | ||||
| def max_(context, mapping, args, **kwargs): | def max_(context, mapping, args, **kwargs): | ||||
| """Return the max of an iterable""" | """Return the max of an iterable""" | ||||
| if len(args) != 1: | if len(args) != 1: | ||||
| # i18n: "max" is a keyword | # i18n: "max" is a keyword | ||||
| raise error.ParseError(_("max expects one argument")) | raise error.ParseError(_("max expects one argument")) | ||||
| nbytes = min(limit, size) | nbytes = min(limit, size) | ||||
| s = nbytes and f.read(nbytes) | s = nbytes and f.read(nbytes) | ||||
| if not s: | if not s: | ||||
| break | break | ||||
| if limit: | if limit: | ||||
| limit -= len(s) | limit -= len(s) | ||||
| yield s | yield s | ||||
| def makedate(timestamp=None): | |||||
| '''Return a unix timestamp (or the current time) as a (unixtime, | |||||
| offset) tuple based off the local timezone.''' | |||||
| if timestamp is None: | |||||
| timestamp = time.time() | |||||
| if timestamp < 0: | |||||
| hint = _("check your clock") | |||||
| raise Abort(_("negative timestamp: %d") % timestamp, hint=hint) | |||||
| delta = (datetime.datetime.utcfromtimestamp(timestamp) - | |||||
| datetime.datetime.fromtimestamp(timestamp)) | |||||
| tz = delta.days * 86400 + delta.seconds | |||||
| return timestamp, tz | |||||
| def datestr(date=None, format='%a %b %d %H:%M:%S %Y %1%2'): | def datestr(date=None, format='%a %b %d %H:%M:%S %Y %1%2'): | ||||
| """represent a (unixtime, offset) tuple as a localized time. | """represent a (unixtime, offset) tuple as a localized time. | ||||
| unixtime is seconds since the epoch, and offset is the time zone's | unixtime is seconds since the epoch, and offset is the time zone's | ||||
| number of seconds away from UTC. | number of seconds away from UTC. | ||||
| >>> datestr((0, 0)) | >>> datestr((0, 0)) | ||||
| 'Thu Jan 01 00:00:00 1970 +0000' | 'Thu Jan 01 00:00:00 1970 +0000' | ||||
| >>> datestr((42, 0)) | >>> datestr((42, 0)) | ||||
| 'Thu Jan 01 00:00:42 1970 +0000' | 'Thu Jan 01 00:00:42 1970 +0000' | ||||
| >>> datestr((-42, 0)) | >>> datestr((-42, 0)) | ||||
| 'Wed Dec 31 23:59:18 1969 +0000' | 'Wed Dec 31 23:59:18 1969 +0000' | ||||
| >>> datestr((0x7fffffff, 0)) | >>> datestr((0x7fffffff, 0)) | ||||
| 'Tue Jan 19 03:14:07 2038 +0000' | 'Tue Jan 19 03:14:07 2038 +0000' | ||||
| >>> datestr((-0x80000000, 0)) | >>> datestr((-0x80000000, 0)) | ||||
| 'Fri Dec 13 20:45:52 1901 +0000' | 'Fri Dec 13 20:45:52 1901 +0000' | ||||
| """ | """ | ||||
| t, tz = date or makedate() | t, tz = date or dateutil.makedate() | ||||
| if "%1" in format or "%2" in format or "%z" in format: | if "%1" in format or "%2" in format or "%z" in format: | ||||
| sign = (tz > 0) and "-" or "+" | sign = (tz > 0) and "-" or "+" | ||||
| minutes = abs(tz) // 60 | minutes = abs(tz) // 60 | ||||
| q, r = divmod(minutes, 60) | q, r = divmod(minutes, 60) | ||||
| format = format.replace("%z", "%1%2") | format = format.replace("%z", "%1%2") | ||||
| format = format.replace("%1", "%c%02d" % (sign, q)) | format = format.replace("%1", "%c%02d" % (sign, q)) | ||||
| format = format.replace("%2", "%02d" % r) | format = format.replace("%2", "%02d" % r) | ||||
| d = t - tz | d = t - tz | ||||
| >>> parsedate(b' today ') == parsedate( | >>> parsedate(b' today ') == parsedate( | ||||
| ... datetime.date.today().strftime('%b %d').encode('ascii')) | ... datetime.date.today().strftime('%b %d').encode('ascii')) | ||||
| True | True | ||||
| >>> parsedate(b'yesterday ') == parsedate( | >>> parsedate(b'yesterday ') == parsedate( | ||||
| ... (datetime.date.today() - datetime.timedelta(days=1) | ... (datetime.date.today() - datetime.timedelta(days=1) | ||||
| ... ).strftime('%b %d').encode('ascii')) | ... ).strftime('%b %d').encode('ascii')) | ||||
| True | True | ||||
| >>> now, tz = makedate() | >>> now, tz = dateutil.makedate() | ||||
| >>> strnow, strtz = parsedate(b'now') | >>> strnow, strtz = parsedate(b'now') | ||||
| >>> (strnow - now) < 1 | >>> (strnow - now) < 1 | ||||
| True | True | ||||
| >>> tz == strtz | >>> tz == strtz | ||||
| True | True | ||||
| """ | """ | ||||
| if bias is None: | if bias is None: | ||||
| bias = {} | bias = {} | ||||
| if not date: | if not date: | ||||
| return 0, 0 | return 0, 0 | ||||
| if isinstance(date, tuple) and len(date) == 2: | if isinstance(date, tuple) and len(date) == 2: | ||||
| return date | return date | ||||
| if not formats: | if not formats: | ||||
| formats = defaultdateformats | formats = defaultdateformats | ||||
| date = date.strip() | date = date.strip() | ||||
| if date == 'now' or date == _('now'): | if date == 'now' or date == _('now'): | ||||
| return makedate() | return dateutil.makedate() | ||||
| if date == 'today' or date == _('today'): | if date == 'today' or date == _('today'): | ||||
| date = datetime.date.today().strftime(r'%b %d') | date = datetime.date.today().strftime(r'%b %d') | ||||
| date = encoding.strtolocal(date) | date = encoding.strtolocal(date) | ||||
| elif date == 'yesterday' or date == _('yesterday'): | elif date == 'yesterday' or date == _('yesterday'): | ||||
| date = (datetime.date.today() - | date = (datetime.date.today() - | ||||
| datetime.timedelta(days=1)).strftime(r'%b %d') | datetime.timedelta(days=1)).strftime(r'%b %d') | ||||
| date = encoding.strtolocal(date) | date = encoding.strtolocal(date) | ||||
| try: | try: | ||||
| when, offset = map(int, date.split(' ')) | when, offset = map(int, date.split(' ')) | ||||
| except ValueError: | except ValueError: | ||||
| # fill out defaults | # fill out defaults | ||||
| now = makedate() | now = dateutil.makedate() | ||||
| defaults = {} | defaults = {} | ||||
| for part in ("d", "mb", "yY", "HI", "M", "S"): | for part in ("d", "mb", "yY", "HI", "M", "S"): | ||||
| # this piece is for rounding the specific end of unknowns | # this piece is for rounding the specific end of unknowns | ||||
| b = bias.get(part) | b = bias.get(part) | ||||
| if b is None: | if b is None: | ||||
| if part[0:1] in "HMS": | if part[0:1] in "HMS": | ||||
| b = "00" | b = "00" | ||||
| else: | else: | ||||
| elif date[0] == "-": | elif date[0] == "-": | ||||
| try: | try: | ||||
| days = int(date[1:]) | days = int(date[1:]) | ||||
| except ValueError: | except ValueError: | ||||
| raise Abort(_("invalid day spec: %s") % date[1:]) | raise Abort(_("invalid day spec: %s") % date[1:]) | ||||
| if days < 0: | if days < 0: | ||||
| raise Abort(_("%s must be nonnegative (see 'hg help dates')") | raise Abort(_("%s must be nonnegative (see 'hg help dates')") | ||||
| % date[1:]) | % date[1:]) | ||||
| when = makedate()[0] - days * 3600 * 24 | when = dateutil.makedate()[0] - days * 3600 * 24 | ||||
| return lambda x: x >= when | return lambda x: x >= when | ||||
| elif " to " in date: | elif " to " in date: | ||||
| a, b = date.split(" to ") | a, b = date.split(" to ") | ||||
| start, stop = lower(a), upper(b) | start, stop = lower(a), upper(b) | ||||
| return lambda x: x >= start and x <= stop | return lambda x: x >= start and x <= stop | ||||
| else: | else: | ||||
| start, stop = lower(date), upper(date) | start, stop = lower(date), upper(date) | ||||
| return lambda x: x >= start and x <= stop | return lambda x: x >= start and x <= stop | ||||
| ### | ### | ||||
| # Deprecation warnings for util.py splitting | # Deprecation warnings for util.py splitting | ||||
| ### | ### | ||||
| defaultdateformats = dateutil.defaultdateformats | defaultdateformats = dateutil.defaultdateformats | ||||
| extendeddateformats = dateutil.extendeddateformats | extendeddateformats = dateutil.extendeddateformats | ||||
| def makedate(*args, **kwargs): | |||||
| msg = ("'util.makedate' is deprecated, " | |||||
| "use 'utils.dateutil.makedate'") | |||||
| nouideprecwarn(msg, "4.6") | |||||
| return dateutil.makedate(*args, **kwargs) | |||||
| # util.py - Mercurial utility functions relative to dates | # util.py - Mercurial utility functions relative to dates | ||||
| # | # | ||||
| # Copyright 2018 Boris Feld <boris.feld@octobus.net> | # Copyright 2018 Boris Feld <boris.feld@octobus.net> | ||||
| # | # | ||||
| # This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
| # GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
| from __future__ import absolute_import, print_function | from __future__ import absolute_import, print_function | ||||
| import datetime | |||||
| import time | |||||
| from ..i18n import _ | |||||
| from .. import ( | |||||
| error, | |||||
| ) | |||||
| # used by parsedate | # used by parsedate | ||||
| defaultdateformats = ( | defaultdateformats = ( | ||||
| '%Y-%m-%dT%H:%M:%S', # the 'real' ISO8601 | '%Y-%m-%dT%H:%M:%S', # the 'real' ISO8601 | ||||
| '%Y-%m-%dT%H:%M', # without seconds | '%Y-%m-%dT%H:%M', # without seconds | ||||
| '%Y-%m-%dT%H%M%S', # another awful but legal variant without : | '%Y-%m-%dT%H%M%S', # another awful but legal variant without : | ||||
| '%Y-%m-%dT%H%M', # without seconds | '%Y-%m-%dT%H%M', # without seconds | ||||
| '%Y-%m-%d %H:%M:%S', # our common legal variant | '%Y-%m-%d %H:%M:%S', # our common legal variant | ||||
| '%Y-%m-%d %H:%M', # without seconds | '%Y-%m-%d %H:%M', # without seconds | ||||
| ) | ) | ||||
| extendeddateformats = defaultdateformats + ( | extendeddateformats = defaultdateformats + ( | ||||
| "%Y", | "%Y", | ||||
| "%Y-%m", | "%Y-%m", | ||||
| "%b", | "%b", | ||||
| "%b %Y", | "%b %Y", | ||||
| ) | ) | ||||
| def makedate(timestamp=None): | |||||
| '''Return a unix timestamp (or the current time) as a (unixtime, | |||||
| offset) tuple based off the local timezone.''' | |||||
| if timestamp is None: | |||||
| timestamp = time.time() | |||||
| if timestamp < 0: | |||||
| hint = _("check your clock") | |||||
| raise error.Abort(_("negative timestamp: %d") % timestamp, hint=hint) | |||||
| delta = (datetime.datetime.utcfromtimestamp(timestamp) - | |||||
| datetime.datetime.fromtimestamp(timestamp)) | |||||
| tz = delta.days * 86400 + delta.seconds | |||||
| return timestamp, tz | |||||
| Tests for the journal extension; records bookmark locations. | Tests for the journal extension; records bookmark locations. | ||||
| $ cat >> testmocks.py << EOF | $ cat >> testmocks.py << EOF | ||||
| > # mock out util.getuser() and util.makedate() to supply testable values | > # mock out util.getuser() and util.makedate() to supply testable values | ||||
| > import os | > import os | ||||
| > from mercurial import util | > from mercurial import util | ||||
| > from mercurial.utils import dateutil | |||||
| > def mockgetuser(): | > def mockgetuser(): | ||||
| > return 'foobar' | > return 'foobar' | ||||
| > | > | ||||
| > def mockmakedate(): | > def mockmakedate(): | ||||
| > filename = os.path.join(os.environ['TESTTMP'], 'testtime') | > filename = os.path.join(os.environ['TESTTMP'], 'testtime') | ||||
| > try: | > try: | ||||
| > with open(filename, 'rb') as timef: | > with open(filename, 'rb') as timef: | ||||
| > time = float(timef.read()) + 1 | > time = float(timef.read()) + 1 | ||||
| > except IOError: | > except IOError: | ||||
| > time = 0.0 | > time = 0.0 | ||||
| > with open(filename, 'wb') as timef: | > with open(filename, 'wb') as timef: | ||||
| > timef.write(str(time)) | > timef.write(str(time)) | ||||
| > return (time, 0) | > return (time, 0) | ||||
| > | > | ||||
| > util.getuser = mockgetuser | > util.getuser = mockgetuser | ||||
| > util.makedate = mockmakedate | > dateutil.makedate = mockmakedate | ||||
| > EOF | > EOF | ||||
| $ cat >> $HGRCPATH << EOF | $ cat >> $HGRCPATH << EOF | ||||
| > [extensions] | > [extensions] | ||||
| > journal= | > journal= | ||||
| > testmocks=`pwd`/testmocks.py | > testmocks=`pwd`/testmocks.py | ||||
| > EOF | > EOF | ||||