##// END OF EJS Templates
configitems: register the 'progress.format' config
Boris Feld -
r34747:54fa3db5 default
parent child Browse files
Show More
@@ -1,979 +1,982 b''
1 1 # configitems.py - centralized declaration of configuration option
2 2 #
3 3 # Copyright 2017 Pierre-Yves David <pierre-yves.david@octobus.net>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import functools
11 11 import re
12 12
13 13 from . import (
14 14 encoding,
15 15 error,
16 16 )
17 17
18 18 def loadconfigtable(ui, extname, configtable):
19 19 """update config item known to the ui with the extension ones"""
20 20 for section, items in configtable.items():
21 21 knownitems = ui._knownconfig.setdefault(section, {})
22 22 knownkeys = set(knownitems)
23 23 newkeys = set(items)
24 24 for key in sorted(knownkeys & newkeys):
25 25 msg = "extension '%s' overwrite config item '%s.%s'"
26 26 msg %= (extname, section, key)
27 27 ui.develwarn(msg, config='warn-config')
28 28
29 29 knownitems.update(items)
30 30
31 31 class configitem(object):
32 32 """represent a known config item
33 33
34 34 :section: the official config section where to find this item,
35 35 :name: the official name within the section,
36 36 :default: default value for this item,
37 37 :alias: optional list of tuples as alternatives,
38 38 :generic: this is a generic definition, match name using regular expression.
39 39 """
40 40
41 41 def __init__(self, section, name, default=None, alias=(),
42 42 generic=False, priority=0):
43 43 self.section = section
44 44 self.name = name
45 45 self.default = default
46 46 self.alias = list(alias)
47 47 self.generic = generic
48 48 self.priority = priority
49 49 self._re = None
50 50 if generic:
51 51 self._re = re.compile(self.name)
52 52
53 53 class itemregister(dict):
54 54 """A specialized dictionary that can handle wild-card selection"""
55 55
56 56 def __init__(self):
57 57 super(itemregister, self).__init__()
58 58 self._generics = set()
59 59
60 60 def update(self, other):
61 61 super(itemregister, self).update(other)
62 62 self._generics.update(other._generics)
63 63
64 64 def __setitem__(self, key, item):
65 65 super(itemregister, self).__setitem__(key, item)
66 66 if item.generic:
67 67 self._generics.add(item)
68 68
69 69 def get(self, key):
70 70 if key in self:
71 71 return self[key]
72 72
73 73 # search for a matching generic item
74 74 generics = sorted(self._generics, key=(lambda x: (x.priority, x.name)))
75 75 for item in generics:
76 76 if item._re.match(key):
77 77 return item
78 78
79 79 # fallback to dict get
80 80 return super(itemregister, self).get(key)
81 81
82 82 coreitems = {}
83 83
84 84 def _register(configtable, *args, **kwargs):
85 85 item = configitem(*args, **kwargs)
86 86 section = configtable.setdefault(item.section, itemregister())
87 87 if item.name in section:
88 88 msg = "duplicated config item registration for '%s.%s'"
89 89 raise error.ProgrammingError(msg % (item.section, item.name))
90 90 section[item.name] = item
91 91
92 92 # special value for case where the default is derived from other values
93 93 dynamicdefault = object()
94 94
95 95 # Registering actual config items
96 96
97 97 def getitemregister(configtable):
98 98 return functools.partial(_register, configtable)
99 99
100 100 coreconfigitem = getitemregister(coreitems)
101 101
102 102 coreconfigitem('alias', '.*',
103 103 default=None,
104 104 generic=True,
105 105 )
106 106 coreconfigitem('annotate', 'nodates',
107 107 default=False,
108 108 )
109 109 coreconfigitem('annotate', 'showfunc',
110 110 default=False,
111 111 )
112 112 coreconfigitem('annotate', 'unified',
113 113 default=None,
114 114 )
115 115 coreconfigitem('annotate', 'git',
116 116 default=False,
117 117 )
118 118 coreconfigitem('annotate', 'ignorews',
119 119 default=False,
120 120 )
121 121 coreconfigitem('annotate', 'ignorewsamount',
122 122 default=False,
123 123 )
124 124 coreconfigitem('annotate', 'ignoreblanklines',
125 125 default=False,
126 126 )
127 127 coreconfigitem('annotate', 'ignorewseol',
128 128 default=False,
129 129 )
130 130 coreconfigitem('annotate', 'nobinary',
131 131 default=False,
132 132 )
133 133 coreconfigitem('annotate', 'noprefix',
134 134 default=False,
135 135 )
136 136 coreconfigitem('auth', 'cookiefile',
137 137 default=None,
138 138 )
139 139 # bookmarks.pushing: internal hack for discovery
140 140 coreconfigitem('bookmarks', 'pushing',
141 141 default=list,
142 142 )
143 143 # bundle.mainreporoot: internal hack for bundlerepo
144 144 coreconfigitem('bundle', 'mainreporoot',
145 145 default='',
146 146 )
147 147 # bundle.reorder: experimental config
148 148 coreconfigitem('bundle', 'reorder',
149 149 default='auto',
150 150 )
151 151 coreconfigitem('censor', 'policy',
152 152 default='abort',
153 153 )
154 154 coreconfigitem('chgserver', 'idletimeout',
155 155 default=3600,
156 156 )
157 157 coreconfigitem('chgserver', 'skiphash',
158 158 default=False,
159 159 )
160 160 coreconfigitem('cmdserver', 'log',
161 161 default=None,
162 162 )
163 163 coreconfigitem('color', '.*',
164 164 default=None,
165 165 generic=True,
166 166 )
167 167 coreconfigitem('color', 'mode',
168 168 default='auto',
169 169 )
170 170 coreconfigitem('color', 'pagermode',
171 171 default=dynamicdefault,
172 172 )
173 173 coreconfigitem('commands', 'status.relative',
174 174 default=False,
175 175 )
176 176 coreconfigitem('commands', 'status.skipstates',
177 177 default=[],
178 178 )
179 179 coreconfigitem('commands', 'status.verbose',
180 180 default=False,
181 181 )
182 182 coreconfigitem('commands', 'update.check',
183 183 default=None,
184 184 )
185 185 coreconfigitem('commands', 'update.requiredest',
186 186 default=False,
187 187 )
188 188 coreconfigitem('committemplate', '.*',
189 189 default=None,
190 190 generic=True,
191 191 )
192 192 coreconfigitem('debug', 'dirstate.delaywrite',
193 193 default=0,
194 194 )
195 195 coreconfigitem('defaults', '.*',
196 196 default=None,
197 197 generic=True,
198 198 )
199 199 coreconfigitem('devel', 'all-warnings',
200 200 default=False,
201 201 )
202 202 coreconfigitem('devel', 'bundle2.debug',
203 203 default=False,
204 204 )
205 205 coreconfigitem('devel', 'cache-vfs',
206 206 default=None,
207 207 )
208 208 coreconfigitem('devel', 'check-locks',
209 209 default=False,
210 210 )
211 211 coreconfigitem('devel', 'check-relroot',
212 212 default=False,
213 213 )
214 214 coreconfigitem('devel', 'default-date',
215 215 default=None,
216 216 )
217 217 coreconfigitem('devel', 'deprec-warn',
218 218 default=False,
219 219 )
220 220 coreconfigitem('devel', 'disableloaddefaultcerts',
221 221 default=False,
222 222 )
223 223 coreconfigitem('devel', 'warn-empty-changegroup',
224 224 default=False,
225 225 )
226 226 coreconfigitem('devel', 'legacy.exchange',
227 227 default=list,
228 228 )
229 229 coreconfigitem('devel', 'servercafile',
230 230 default='',
231 231 )
232 232 coreconfigitem('devel', 'serverexactprotocol',
233 233 default='',
234 234 )
235 235 coreconfigitem('devel', 'serverrequirecert',
236 236 default=False,
237 237 )
238 238 coreconfigitem('devel', 'strip-obsmarkers',
239 239 default=True,
240 240 )
241 241 coreconfigitem('devel', 'warn-config',
242 242 default=None,
243 243 )
244 244 coreconfigitem('devel', 'warn-config-default',
245 245 default=None,
246 246 )
247 247 coreconfigitem('devel', 'user.obsmarker',
248 248 default=None,
249 249 )
250 250 coreconfigitem('diff', 'nodates',
251 251 default=False,
252 252 )
253 253 coreconfigitem('diff', 'showfunc',
254 254 default=False,
255 255 )
256 256 coreconfigitem('diff', 'unified',
257 257 default=None,
258 258 )
259 259 coreconfigitem('diff', 'git',
260 260 default=False,
261 261 )
262 262 coreconfigitem('diff', 'ignorews',
263 263 default=False,
264 264 )
265 265 coreconfigitem('diff', 'ignorewsamount',
266 266 default=False,
267 267 )
268 268 coreconfigitem('diff', 'ignoreblanklines',
269 269 default=False,
270 270 )
271 271 coreconfigitem('diff', 'ignorewseol',
272 272 default=False,
273 273 )
274 274 coreconfigitem('diff', 'nobinary',
275 275 default=False,
276 276 )
277 277 coreconfigitem('diff', 'noprefix',
278 278 default=False,
279 279 )
280 280 coreconfigitem('email', 'bcc',
281 281 default=None,
282 282 )
283 283 coreconfigitem('email', 'cc',
284 284 default=None,
285 285 )
286 286 coreconfigitem('email', 'charsets',
287 287 default=list,
288 288 )
289 289 coreconfigitem('email', 'from',
290 290 default=None,
291 291 )
292 292 coreconfigitem('email', 'method',
293 293 default='smtp',
294 294 )
295 295 coreconfigitem('email', 'reply-to',
296 296 default=None,
297 297 )
298 298 coreconfigitem('experimental', 'allowdivergence',
299 299 default=False,
300 300 )
301 301 coreconfigitem('experimental', 'archivemetatemplate',
302 302 default=dynamicdefault,
303 303 )
304 304 coreconfigitem('experimental', 'bundle-phases',
305 305 default=False,
306 306 )
307 307 coreconfigitem('experimental', 'bundle2-advertise',
308 308 default=True,
309 309 )
310 310 coreconfigitem('experimental', 'bundle2-output-capture',
311 311 default=False,
312 312 )
313 313 coreconfigitem('experimental', 'bundle2.pushback',
314 314 default=False,
315 315 )
316 316 coreconfigitem('experimental', 'bundle2lazylocking',
317 317 default=False,
318 318 )
319 319 coreconfigitem('experimental', 'bundlecomplevel',
320 320 default=None,
321 321 )
322 322 coreconfigitem('experimental', 'changegroup3',
323 323 default=False,
324 324 )
325 325 coreconfigitem('experimental', 'clientcompressionengines',
326 326 default=list,
327 327 )
328 328 coreconfigitem('experimental', 'copytrace',
329 329 default='on',
330 330 )
331 331 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
332 332 default=100,
333 333 )
334 334 coreconfigitem('experimental', 'crecordtest',
335 335 default=None,
336 336 )
337 337 coreconfigitem('experimental', 'editortmpinhg',
338 338 default=False,
339 339 )
340 340 coreconfigitem('experimental', 'maxdeltachainspan',
341 341 default=-1,
342 342 )
343 343 coreconfigitem('experimental', 'mmapindexthreshold',
344 344 default=None,
345 345 )
346 346 coreconfigitem('experimental', 'nonnormalparanoidcheck',
347 347 default=False,
348 348 )
349 349 coreconfigitem('experimental', 'stabilization',
350 350 default=list,
351 351 alias=[('experimental', 'evolution')],
352 352 )
353 353 coreconfigitem('experimental', 'stabilization.bundle-obsmarker',
354 354 default=False,
355 355 alias=[('experimental', 'evolution.bundle-obsmarker')],
356 356 )
357 357 coreconfigitem('experimental', 'stabilization.track-operation',
358 358 default=True,
359 359 alias=[('experimental', 'evolution.track-operation')]
360 360 )
361 361 coreconfigitem('experimental', 'exportableenviron',
362 362 default=list,
363 363 )
364 364 coreconfigitem('experimental', 'extendedheader.index',
365 365 default=None,
366 366 )
367 367 coreconfigitem('experimental', 'extendedheader.similarity',
368 368 default=False,
369 369 )
370 370 coreconfigitem('experimental', 'format.compression',
371 371 default='zlib',
372 372 )
373 373 coreconfigitem('experimental', 'graphshorten',
374 374 default=False,
375 375 )
376 376 coreconfigitem('experimental', 'graphstyle.parent',
377 377 default=dynamicdefault,
378 378 )
379 379 coreconfigitem('experimental', 'graphstyle.missing',
380 380 default=dynamicdefault,
381 381 )
382 382 coreconfigitem('experimental', 'graphstyle.grandparent',
383 383 default=dynamicdefault,
384 384 )
385 385 coreconfigitem('experimental', 'hook-track-tags',
386 386 default=False,
387 387 )
388 388 coreconfigitem('experimental', 'httppostargs',
389 389 default=False,
390 390 )
391 391 coreconfigitem('experimental', 'manifestv2',
392 392 default=False,
393 393 )
394 394 coreconfigitem('experimental', 'mergedriver',
395 395 default=None,
396 396 )
397 397 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
398 398 default=False,
399 399 )
400 400 coreconfigitem('experimental', 'rebase.multidest',
401 401 default=False,
402 402 )
403 403 coreconfigitem('experimental', 'revertalternateinteractivemode',
404 404 default=True,
405 405 )
406 406 coreconfigitem('experimental', 'revlogv2',
407 407 default=None,
408 408 )
409 409 coreconfigitem('experimental', 'spacemovesdown',
410 410 default=False,
411 411 )
412 412 coreconfigitem('experimental', 'treemanifest',
413 413 default=False,
414 414 )
415 415 # Deprecated, remove after 4.4 release
416 416 coreconfigitem('experimental', 'updatecheck',
417 417 default=None,
418 418 )
419 419 coreconfigitem('extensions', '.*',
420 420 default=None,
421 421 generic=True,
422 422 )
423 423 coreconfigitem('format', 'aggressivemergedeltas',
424 424 default=False,
425 425 )
426 426 coreconfigitem('format', 'chunkcachesize',
427 427 default=None,
428 428 )
429 429 coreconfigitem('format', 'dotencode',
430 430 default=True,
431 431 )
432 432 coreconfigitem('format', 'generaldelta',
433 433 default=False,
434 434 )
435 435 coreconfigitem('format', 'manifestcachesize',
436 436 default=None,
437 437 )
438 438 coreconfigitem('format', 'maxchainlen',
439 439 default=None,
440 440 )
441 441 coreconfigitem('format', 'obsstore-version',
442 442 default=None,
443 443 )
444 444 coreconfigitem('format', 'usefncache',
445 445 default=True,
446 446 )
447 447 coreconfigitem('format', 'usegeneraldelta',
448 448 default=True,
449 449 )
450 450 coreconfigitem('format', 'usestore',
451 451 default=True,
452 452 )
453 453 coreconfigitem('hooks', '.*',
454 454 default=dynamicdefault,
455 455 generic=True,
456 456 )
457 457 coreconfigitem('hostsecurity', 'ciphers',
458 458 default=None,
459 459 )
460 460 coreconfigitem('hostsecurity', 'disabletls10warning',
461 461 default=False,
462 462 )
463 463 coreconfigitem('http_proxy', 'always',
464 464 default=False,
465 465 )
466 466 coreconfigitem('http_proxy', 'host',
467 467 default=None,
468 468 )
469 469 coreconfigitem('http_proxy', 'no',
470 470 default=list,
471 471 )
472 472 coreconfigitem('http_proxy', 'passwd',
473 473 default=None,
474 474 )
475 475 coreconfigitem('http_proxy', 'user',
476 476 default=None,
477 477 )
478 478 coreconfigitem('logtoprocess', 'commandexception',
479 479 default=None,
480 480 )
481 481 coreconfigitem('logtoprocess', 'commandfinish',
482 482 default=None,
483 483 )
484 484 coreconfigitem('logtoprocess', 'command',
485 485 default=None,
486 486 )
487 487 coreconfigitem('logtoprocess', 'develwarn',
488 488 default=None,
489 489 )
490 490 coreconfigitem('logtoprocess', 'uiblocked',
491 491 default=None,
492 492 )
493 493 coreconfigitem('merge', 'checkunknown',
494 494 default='abort',
495 495 )
496 496 coreconfigitem('merge', 'checkignored',
497 497 default='abort',
498 498 )
499 499 coreconfigitem('merge', 'followcopies',
500 500 default=True,
501 501 )
502 502 coreconfigitem('merge', 'preferancestor',
503 503 default=lambda: ['*'],
504 504 )
505 505 coreconfigitem('pager', 'attend-.*',
506 506 default=dynamicdefault,
507 507 generic=True,
508 508 )
509 509 coreconfigitem('pager', 'ignore',
510 510 default=list,
511 511 )
512 512 coreconfigitem('pager', 'pager',
513 513 default=dynamicdefault,
514 514 )
515 515 coreconfigitem('patch', 'eol',
516 516 default='strict',
517 517 )
518 518 coreconfigitem('patch', 'fuzz',
519 519 default=2,
520 520 )
521 521 coreconfigitem('paths', 'default',
522 522 default=None,
523 523 )
524 524 coreconfigitem('paths', 'default-push',
525 525 default=None,
526 526 )
527 527 coreconfigitem('paths', '.*',
528 528 default=None,
529 529 generic=True,
530 530 )
531 531 coreconfigitem('phases', 'checksubrepos',
532 532 default='follow',
533 533 )
534 534 coreconfigitem('phases', 'new-commit',
535 535 default='draft',
536 536 )
537 537 coreconfigitem('phases', 'publish',
538 538 default=True,
539 539 )
540 540 coreconfigitem('profiling', 'enabled',
541 541 default=False,
542 542 )
543 543 coreconfigitem('profiling', 'format',
544 544 default='text',
545 545 )
546 546 coreconfigitem('profiling', 'freq',
547 547 default=1000,
548 548 )
549 549 coreconfigitem('profiling', 'limit',
550 550 default=30,
551 551 )
552 552 coreconfigitem('profiling', 'nested',
553 553 default=0,
554 554 )
555 555 coreconfigitem('profiling', 'output',
556 556 default=None,
557 557 )
558 558 coreconfigitem('profiling', 'showmax',
559 559 default=0.999,
560 560 )
561 561 coreconfigitem('profiling', 'showmin',
562 562 default=dynamicdefault,
563 563 )
564 564 coreconfigitem('profiling', 'sort',
565 565 default='inlinetime',
566 566 )
567 567 coreconfigitem('profiling', 'statformat',
568 568 default='hotpath',
569 569 )
570 570 coreconfigitem('profiling', 'type',
571 571 default='stat',
572 572 )
573 573 coreconfigitem('progress', 'assume-tty',
574 574 default=False,
575 575 )
576 576 coreconfigitem('progress', 'changedelay',
577 577 default=1,
578 578 )
579 579 coreconfigitem('progress', 'clear-complete',
580 580 default=True,
581 581 )
582 582 coreconfigitem('progress', 'debug',
583 583 default=False,
584 584 )
585 585 coreconfigitem('progress', 'delay',
586 586 default=3,
587 587 )
588 588 coreconfigitem('progress', 'disable',
589 589 default=False,
590 590 )
591 591 coreconfigitem('progress', 'estimateinterval',
592 592 default=60.0,
593 593 )
594 coreconfigitem('progress', 'format',
595 default=lambda: ['topic', 'bar', 'number', 'estimate'],
596 )
594 597 coreconfigitem('progress', 'refresh',
595 598 default=0.1,
596 599 )
597 600 coreconfigitem('progress', 'width',
598 601 default=dynamicdefault,
599 602 )
600 603 coreconfigitem('push', 'pushvars.server',
601 604 default=False,
602 605 )
603 606 coreconfigitem('server', 'bundle1',
604 607 default=True,
605 608 )
606 609 coreconfigitem('server', 'bundle1gd',
607 610 default=None,
608 611 )
609 612 coreconfigitem('server', 'bundle1.pull',
610 613 default=None,
611 614 )
612 615 coreconfigitem('server', 'bundle1gd.pull',
613 616 default=None,
614 617 )
615 618 coreconfigitem('server', 'bundle1.push',
616 619 default=None,
617 620 )
618 621 coreconfigitem('server', 'bundle1gd.push',
619 622 default=None,
620 623 )
621 624 coreconfigitem('server', 'compressionengines',
622 625 default=list,
623 626 )
624 627 coreconfigitem('server', 'concurrent-push-mode',
625 628 default='strict',
626 629 )
627 630 coreconfigitem('server', 'disablefullbundle',
628 631 default=False,
629 632 )
630 633 coreconfigitem('server', 'maxhttpheaderlen',
631 634 default=1024,
632 635 )
633 636 coreconfigitem('server', 'preferuncompressed',
634 637 default=False,
635 638 )
636 639 coreconfigitem('server', 'uncompressed',
637 640 default=True,
638 641 )
639 642 coreconfigitem('server', 'uncompressedallowsecret',
640 643 default=False,
641 644 )
642 645 coreconfigitem('server', 'validate',
643 646 default=False,
644 647 )
645 648 coreconfigitem('server', 'zliblevel',
646 649 default=-1,
647 650 )
648 651 coreconfigitem('smtp', 'host',
649 652 default=None,
650 653 )
651 654 coreconfigitem('smtp', 'local_hostname',
652 655 default=None,
653 656 )
654 657 coreconfigitem('smtp', 'password',
655 658 default=None,
656 659 )
657 660 coreconfigitem('smtp', 'port',
658 661 default=dynamicdefault,
659 662 )
660 663 coreconfigitem('smtp', 'tls',
661 664 default='none',
662 665 )
663 666 coreconfigitem('smtp', 'username',
664 667 default=None,
665 668 )
666 669 coreconfigitem('sparse', 'missingwarning',
667 670 default=True,
668 671 )
669 672 coreconfigitem('templates', '.*',
670 673 default=None,
671 674 generic=True,
672 675 )
673 676 coreconfigitem('trusted', 'groups',
674 677 default=list,
675 678 )
676 679 coreconfigitem('trusted', 'users',
677 680 default=list,
678 681 )
679 682 coreconfigitem('ui', '_usedassubrepo',
680 683 default=False,
681 684 )
682 685 coreconfigitem('ui', 'allowemptycommit',
683 686 default=False,
684 687 )
685 688 coreconfigitem('ui', 'archivemeta',
686 689 default=True,
687 690 )
688 691 coreconfigitem('ui', 'askusername',
689 692 default=False,
690 693 )
691 694 coreconfigitem('ui', 'clonebundlefallback',
692 695 default=False,
693 696 )
694 697 coreconfigitem('ui', 'clonebundleprefers',
695 698 default=list,
696 699 )
697 700 coreconfigitem('ui', 'clonebundles',
698 701 default=True,
699 702 )
700 703 coreconfigitem('ui', 'color',
701 704 default='auto',
702 705 )
703 706 coreconfigitem('ui', 'commitsubrepos',
704 707 default=False,
705 708 )
706 709 coreconfigitem('ui', 'debug',
707 710 default=False,
708 711 )
709 712 coreconfigitem('ui', 'debugger',
710 713 default=None,
711 714 )
712 715 coreconfigitem('ui', 'fallbackencoding',
713 716 default=None,
714 717 )
715 718 coreconfigitem('ui', 'forcecwd',
716 719 default=None,
717 720 )
718 721 coreconfigitem('ui', 'forcemerge',
719 722 default=None,
720 723 )
721 724 coreconfigitem('ui', 'formatdebug',
722 725 default=False,
723 726 )
724 727 coreconfigitem('ui', 'formatjson',
725 728 default=False,
726 729 )
727 730 coreconfigitem('ui', 'formatted',
728 731 default=None,
729 732 )
730 733 coreconfigitem('ui', 'graphnodetemplate',
731 734 default=None,
732 735 )
733 736 coreconfigitem('ui', 'http2debuglevel',
734 737 default=None,
735 738 )
736 739 coreconfigitem('ui', 'interactive',
737 740 default=None,
738 741 )
739 742 coreconfigitem('ui', 'interface',
740 743 default=None,
741 744 )
742 745 coreconfigitem('ui', 'interface.chunkselector',
743 746 default=None,
744 747 )
745 748 coreconfigitem('ui', 'logblockedtimes',
746 749 default=False,
747 750 )
748 751 coreconfigitem('ui', 'logtemplate',
749 752 default=None,
750 753 )
751 754 coreconfigitem('ui', 'merge',
752 755 default=None,
753 756 )
754 757 coreconfigitem('ui', 'mergemarkers',
755 758 default='basic',
756 759 )
757 760 coreconfigitem('ui', 'mergemarkertemplate',
758 761 default=('{node|short} '
759 762 '{ifeq(tags, "tip", "", '
760 763 'ifeq(tags, "", "", "{tags} "))}'
761 764 '{if(bookmarks, "{bookmarks} ")}'
762 765 '{ifeq(branch, "default", "", "{branch} ")}'
763 766 '- {author|user}: {desc|firstline}')
764 767 )
765 768 coreconfigitem('ui', 'nontty',
766 769 default=False,
767 770 )
768 771 coreconfigitem('ui', 'origbackuppath',
769 772 default=None,
770 773 )
771 774 coreconfigitem('ui', 'paginate',
772 775 default=True,
773 776 )
774 777 coreconfigitem('ui', 'patch',
775 778 default=None,
776 779 )
777 780 coreconfigitem('ui', 'portablefilenames',
778 781 default='warn',
779 782 )
780 783 coreconfigitem('ui', 'promptecho',
781 784 default=False,
782 785 )
783 786 coreconfigitem('ui', 'quiet',
784 787 default=False,
785 788 )
786 789 coreconfigitem('ui', 'quietbookmarkmove',
787 790 default=False,
788 791 )
789 792 coreconfigitem('ui', 'remotecmd',
790 793 default='hg',
791 794 )
792 795 coreconfigitem('ui', 'report_untrusted',
793 796 default=True,
794 797 )
795 798 coreconfigitem('ui', 'rollback',
796 799 default=True,
797 800 )
798 801 coreconfigitem('ui', 'slash',
799 802 default=False,
800 803 )
801 804 coreconfigitem('ui', 'ssh',
802 805 default='ssh',
803 806 )
804 807 coreconfigitem('ui', 'statuscopies',
805 808 default=False,
806 809 )
807 810 coreconfigitem('ui', 'strict',
808 811 default=False,
809 812 )
810 813 coreconfigitem('ui', 'style',
811 814 default='',
812 815 )
813 816 coreconfigitem('ui', 'supportcontact',
814 817 default=None,
815 818 )
816 819 coreconfigitem('ui', 'textwidth',
817 820 default=78,
818 821 )
819 822 coreconfigitem('ui', 'timeout',
820 823 default='600',
821 824 )
822 825 coreconfigitem('ui', 'traceback',
823 826 default=False,
824 827 )
825 828 coreconfigitem('ui', 'tweakdefaults',
826 829 default=False,
827 830 )
828 831 coreconfigitem('ui', 'usehttp2',
829 832 default=False,
830 833 )
831 834 coreconfigitem('ui', 'username',
832 835 alias=[('ui', 'user')]
833 836 )
834 837 coreconfigitem('ui', 'verbose',
835 838 default=False,
836 839 )
837 840 coreconfigitem('verify', 'skipflags',
838 841 default=None,
839 842 )
840 843 coreconfigitem('web', 'allowbz2',
841 844 default=False,
842 845 )
843 846 coreconfigitem('web', 'allowgz',
844 847 default=False,
845 848 )
846 849 coreconfigitem('web', 'allowpull',
847 850 default=True,
848 851 )
849 852 coreconfigitem('web', 'allow_push',
850 853 default=list,
851 854 )
852 855 coreconfigitem('web', 'allowzip',
853 856 default=False,
854 857 )
855 858 coreconfigitem('web', 'cache',
856 859 default=True,
857 860 )
858 861 coreconfigitem('web', 'contact',
859 862 default=None,
860 863 )
861 864 coreconfigitem('web', 'deny_push',
862 865 default=list,
863 866 )
864 867 coreconfigitem('web', 'guessmime',
865 868 default=False,
866 869 )
867 870 coreconfigitem('web', 'hidden',
868 871 default=False,
869 872 )
870 873 coreconfigitem('web', 'labels',
871 874 default=list,
872 875 )
873 876 coreconfigitem('web', 'logoimg',
874 877 default='hglogo.png',
875 878 )
876 879 coreconfigitem('web', 'logourl',
877 880 default='https://mercurial-scm.org/',
878 881 )
879 882 coreconfigitem('web', 'accesslog',
880 883 default='-',
881 884 )
882 885 coreconfigitem('web', 'address',
883 886 default='',
884 887 )
885 888 coreconfigitem('web', 'allow_archive',
886 889 default=list,
887 890 )
888 891 coreconfigitem('web', 'allow_read',
889 892 default=list,
890 893 )
891 894 coreconfigitem('web', 'baseurl',
892 895 default=None,
893 896 )
894 897 coreconfigitem('web', 'cacerts',
895 898 default=None,
896 899 )
897 900 coreconfigitem('web', 'certificate',
898 901 default=None,
899 902 )
900 903 coreconfigitem('web', 'collapse',
901 904 default=False,
902 905 )
903 906 coreconfigitem('web', 'csp',
904 907 default=None,
905 908 )
906 909 coreconfigitem('web', 'deny_read',
907 910 default=list,
908 911 )
909 912 coreconfigitem('web', 'descend',
910 913 default=True,
911 914 )
912 915 coreconfigitem('web', 'description',
913 916 default="",
914 917 )
915 918 coreconfigitem('web', 'encoding',
916 919 default=lambda: encoding.encoding,
917 920 )
918 921 coreconfigitem('web', 'errorlog',
919 922 default='-',
920 923 )
921 924 coreconfigitem('web', 'ipv6',
922 925 default=False,
923 926 )
924 927 coreconfigitem('web', 'maxchanges',
925 928 default=10,
926 929 )
927 930 coreconfigitem('web', 'maxfiles',
928 931 default=10,
929 932 )
930 933 coreconfigitem('web', 'maxshortchanges',
931 934 default=60,
932 935 )
933 936 coreconfigitem('web', 'motd',
934 937 default='',
935 938 )
936 939 coreconfigitem('web', 'name',
937 940 default=dynamicdefault,
938 941 )
939 942 coreconfigitem('web', 'port',
940 943 default=8000,
941 944 )
942 945 coreconfigitem('web', 'prefix',
943 946 default='',
944 947 )
945 948 coreconfigitem('web', 'push_ssl',
946 949 default=True,
947 950 )
948 951 coreconfigitem('web', 'refreshinterval',
949 952 default=20,
950 953 )
951 954 coreconfigitem('web', 'stripes',
952 955 default=1,
953 956 )
954 957 coreconfigitem('web', 'style',
955 958 default='paper',
956 959 )
957 960 coreconfigitem('web', 'templates',
958 961 default=None,
959 962 )
960 963 coreconfigitem('web', 'view',
961 964 default='served',
962 965 )
963 966 coreconfigitem('worker', 'backgroundclose',
964 967 default=dynamicdefault,
965 968 )
966 969 # Windows defaults to a limit of 512 open files. A buffer of 128
967 970 # should give us enough headway.
968 971 coreconfigitem('worker', 'backgroundclosemaxqueue',
969 972 default=384,
970 973 )
971 974 coreconfigitem('worker', 'backgroundcloseminfilecount',
972 975 default=2048,
973 976 )
974 977 coreconfigitem('worker', 'backgroundclosethreadcount',
975 978 default=4,
976 979 )
977 980 coreconfigitem('worker', 'numcpus',
978 981 default=None,
979 982 )
@@ -1,305 +1,303 b''
1 1 # progress.py progress bars related code
2 2 #
3 3 # Copyright (C) 2010 Augie Fackler <durin42@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import errno
11 11 import threading
12 12 import time
13 13
14 14 from .i18n import _
15 15 from . import encoding
16 16
17 17 def spacejoin(*args):
18 18 return ' '.join(s for s in args if s)
19 19
20 20 def shouldprint(ui):
21 21 return not (ui.quiet or ui.plain('progress')) and (
22 22 ui._isatty(ui.ferr) or ui.configbool('progress', 'assume-tty'))
23 23
24 24 def fmtremaining(seconds):
25 25 """format a number of remaining seconds in human readable way
26 26
27 27 This will properly display seconds, minutes, hours, days if needed"""
28 28 if seconds < 60:
29 29 # i18n: format XX seconds as "XXs"
30 30 return _("%02ds") % (seconds)
31 31 minutes = seconds // 60
32 32 if minutes < 60:
33 33 seconds -= minutes * 60
34 34 # i18n: format X minutes and YY seconds as "XmYYs"
35 35 return _("%dm%02ds") % (minutes, seconds)
36 36 # we're going to ignore seconds in this case
37 37 minutes += 1
38 38 hours = minutes // 60
39 39 minutes -= hours * 60
40 40 if hours < 30:
41 41 # i18n: format X hours and YY minutes as "XhYYm"
42 42 return _("%dh%02dm") % (hours, minutes)
43 43 # we're going to ignore minutes in this case
44 44 hours += 1
45 45 days = hours // 24
46 46 hours -= days * 24
47 47 if days < 15:
48 48 # i18n: format X days and YY hours as "XdYYh"
49 49 return _("%dd%02dh") % (days, hours)
50 50 # we're going to ignore hours in this case
51 51 days += 1
52 52 weeks = days // 7
53 53 days -= weeks * 7
54 54 if weeks < 55:
55 55 # i18n: format X weeks and YY days as "XwYYd"
56 56 return _("%dw%02dd") % (weeks, days)
57 57 # we're going to ignore days and treat a year as 52 weeks
58 58 weeks += 1
59 59 years = weeks // 52
60 60 weeks -= years * 52
61 61 # i18n: format X years and YY weeks as "XyYYw"
62 62 return _("%dy%02dw") % (years, weeks)
63 63
64 64 # file_write() and file_flush() of Python 2 do not restart on EINTR if
65 65 # the file is attached to a "slow" device (e.g. a terminal) and raise
66 66 # IOError. We cannot know how many bytes would be written by file_write(),
67 67 # but a progress text is known to be short enough to be written by a
68 68 # single write() syscall, so we can just retry file_write() with the whole
69 69 # text. (issue5532)
70 70 #
71 71 # This should be a short-term workaround. We'll need to fix every occurrence
72 72 # of write() to a terminal or pipe.
73 73 def _eintrretry(func, *args):
74 74 while True:
75 75 try:
76 76 return func(*args)
77 77 except IOError as err:
78 78 if err.errno == errno.EINTR:
79 79 continue
80 80 raise
81 81
82 82 class progbar(object):
83 83 def __init__(self, ui):
84 84 self.ui = ui
85 85 self._refreshlock = threading.Lock()
86 86 self.resetstate()
87 87
88 88 def resetstate(self):
89 89 self.topics = []
90 90 self.topicstates = {}
91 91 self.starttimes = {}
92 92 self.startvals = {}
93 93 self.printed = False
94 94 self.lastprint = time.time() + float(self.ui.config(
95 95 'progress', 'delay'))
96 96 self.curtopic = None
97 97 self.lasttopic = None
98 98 self.indetcount = 0
99 99 self.refresh = float(self.ui.config(
100 100 'progress', 'refresh'))
101 101 self.changedelay = max(3 * self.refresh,
102 102 float(self.ui.config(
103 103 'progress', 'changedelay')))
104 self.order = self.ui.configlist(
105 'progress', 'format',
106 default=['topic', 'bar', 'number', 'estimate'])
104 self.order = self.ui.configlist('progress', 'format')
107 105 self.estimateinterval = self.ui.configwith(
108 106 float, 'progress', 'estimateinterval')
109 107
110 108 def show(self, now, topic, pos, item, unit, total):
111 109 if not shouldprint(self.ui):
112 110 return
113 111 termwidth = self.width()
114 112 self.printed = True
115 113 head = ''
116 114 needprogress = False
117 115 tail = ''
118 116 for indicator in self.order:
119 117 add = ''
120 118 if indicator == 'topic':
121 119 add = topic
122 120 elif indicator == 'number':
123 121 if total:
124 122 add = ('% ' + str(len(str(total))) +
125 123 's/%s') % (pos, total)
126 124 else:
127 125 add = str(pos)
128 126 elif indicator.startswith('item') and item:
129 127 slice = 'end'
130 128 if '-' in indicator:
131 129 wid = int(indicator.split('-')[1])
132 130 elif '+' in indicator:
133 131 slice = 'beginning'
134 132 wid = int(indicator.split('+')[1])
135 133 else:
136 134 wid = 20
137 135 if slice == 'end':
138 136 add = encoding.trim(item, wid, leftside=True)
139 137 else:
140 138 add = encoding.trim(item, wid)
141 139 add += (wid - encoding.colwidth(add)) * ' '
142 140 elif indicator == 'bar':
143 141 add = ''
144 142 needprogress = True
145 143 elif indicator == 'unit' and unit:
146 144 add = unit
147 145 elif indicator == 'estimate':
148 146 add = self.estimate(topic, pos, total, now)
149 147 elif indicator == 'speed':
150 148 add = self.speed(topic, pos, unit, now)
151 149 if not needprogress:
152 150 head = spacejoin(head, add)
153 151 else:
154 152 tail = spacejoin(tail, add)
155 153 if needprogress:
156 154 used = 0
157 155 if head:
158 156 used += encoding.colwidth(head) + 1
159 157 if tail:
160 158 used += encoding.colwidth(tail) + 1
161 159 progwidth = termwidth - used - 3
162 160 if total and pos <= total:
163 161 amt = pos * progwidth // total
164 162 bar = '=' * (amt - 1)
165 163 if amt > 0:
166 164 bar += '>'
167 165 bar += ' ' * (progwidth - amt)
168 166 else:
169 167 progwidth -= 3
170 168 self.indetcount += 1
171 169 # mod the count by twice the width so we can make the
172 170 # cursor bounce between the right and left sides
173 171 amt = self.indetcount % (2 * progwidth)
174 172 amt -= progwidth
175 173 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
176 174 ' ' * int(abs(amt)))
177 175 prog = ''.join(('[', bar, ']'))
178 176 out = spacejoin(head, prog, tail)
179 177 else:
180 178 out = spacejoin(head, tail)
181 179 self._writeerr('\r' + encoding.trim(out, termwidth))
182 180 self.lasttopic = topic
183 181 self._flusherr()
184 182
185 183 def clear(self):
186 184 if not self.printed or not self.lastprint or not shouldprint(self.ui):
187 185 return
188 186 self._writeerr('\r%s\r' % (' ' * self.width()))
189 187 if self.printed:
190 188 # force immediate re-paint of progress bar
191 189 self.lastprint = 0
192 190
193 191 def complete(self):
194 192 if not shouldprint(self.ui):
195 193 return
196 194 if self.ui.configbool('progress', 'clear-complete'):
197 195 self.clear()
198 196 else:
199 197 self._writeerr('\n')
200 198 self._flusherr()
201 199
202 200 def _flusherr(self):
203 201 _eintrretry(self.ui.ferr.flush)
204 202
205 203 def _writeerr(self, msg):
206 204 _eintrretry(self.ui.ferr.write, msg)
207 205
208 206 def width(self):
209 207 tw = self.ui.termwidth()
210 208 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
211 209
212 210 def estimate(self, topic, pos, total, now):
213 211 if total is None:
214 212 return ''
215 213 initialpos = self.startvals[topic]
216 214 target = total - initialpos
217 215 delta = pos - initialpos
218 216 if delta > 0:
219 217 elapsed = now - self.starttimes[topic]
220 218 seconds = (elapsed * (target - delta)) // delta + 1
221 219 return fmtremaining(seconds)
222 220 return ''
223 221
224 222 def speed(self, topic, pos, unit, now):
225 223 initialpos = self.startvals[topic]
226 224 delta = pos - initialpos
227 225 elapsed = now - self.starttimes[topic]
228 226 if elapsed > 0:
229 227 return _('%d %s/sec') % (delta / elapsed, unit)
230 228 return ''
231 229
232 230 def _oktoprint(self, now):
233 231 '''Check if conditions are met to print - e.g. changedelay elapsed'''
234 232 if (self.lasttopic is None # first time we printed
235 233 # not a topic change
236 234 or self.curtopic == self.lasttopic
237 235 # it's been long enough we should print anyway
238 236 or now - self.lastprint >= self.changedelay):
239 237 return True
240 238 else:
241 239 return False
242 240
243 241 def _calibrateestimate(self, topic, now, pos):
244 242 '''Adjust starttimes and startvals for topic so ETA works better
245 243
246 244 If progress is non-linear (ex. get much slower in the last minute),
247 245 it's more friendly to only use a recent time span for ETA and speed
248 246 calculation.
249 247
250 248 [======================================> ]
251 249 ^^^^^^^
252 250 estimateinterval, only use this for estimation
253 251 '''
254 252 interval = self.estimateinterval
255 253 if interval <= 0:
256 254 return
257 255 elapsed = now - self.starttimes[topic]
258 256 if elapsed > interval:
259 257 delta = pos - self.startvals[topic]
260 258 newdelta = delta * interval / elapsed
261 259 # If a stall happens temporarily, ETA could change dramatically
262 260 # frequently. This is to avoid such dramatical change and make ETA
263 261 # smoother.
264 262 if newdelta < 0.1:
265 263 return
266 264 self.startvals[topic] = pos - newdelta
267 265 self.starttimes[topic] = now - interval
268 266
269 267 def progress(self, topic, pos, item='', unit='', total=None):
270 268 now = time.time()
271 269 self._refreshlock.acquire()
272 270 try:
273 271 if pos is None:
274 272 self.starttimes.pop(topic, None)
275 273 self.startvals.pop(topic, None)
276 274 self.topicstates.pop(topic, None)
277 275 # reset the progress bar if this is the outermost topic
278 276 if self.topics and self.topics[0] == topic and self.printed:
279 277 self.complete()
280 278 self.resetstate()
281 279 # truncate the list of topics assuming all topics within
282 280 # this one are also closed
283 281 if topic in self.topics:
284 282 self.topics = self.topics[:self.topics.index(topic)]
285 283 # reset the last topic to the one we just unwound to,
286 284 # so that higher-level topics will be stickier than
287 285 # lower-level topics
288 286 if self.topics:
289 287 self.lasttopic = self.topics[-1]
290 288 else:
291 289 self.lasttopic = None
292 290 else:
293 291 if topic not in self.topics:
294 292 self.starttimes[topic] = now
295 293 self.startvals[topic] = pos
296 294 self.topics.append(topic)
297 295 self.topicstates[topic] = pos, item, unit, total
298 296 self.curtopic = topic
299 297 self._calibrateestimate(topic, now, pos)
300 298 if now - self.lastprint >= self.refresh and self.topics:
301 299 if self._oktoprint(now):
302 300 self.lastprint = now
303 301 self.show(now, topic, *self.topicstates[topic])
304 302 finally:
305 303 self._refreshlock.release()
General Comments 0
You need to be logged in to leave comments. Login now