##// END OF EJS Templates
progress: remove progress.estimate config...
Jun Wu -
r34314:f428c347 default
parent child Browse files
Show More
@@ -1,668 +1,665
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
12 12 from . import (
13 13 encoding,
14 14 error,
15 15 )
16 16
17 17 def loadconfigtable(ui, extname, configtable):
18 18 """update config item known to the ui with the extension ones"""
19 19 for section, items in configtable.items():
20 20 knownitems = ui._knownconfig.setdefault(section, {})
21 21 knownkeys = set(knownitems)
22 22 newkeys = set(items)
23 23 for key in sorted(knownkeys & newkeys):
24 24 msg = "extension '%s' overwrite config item '%s.%s'"
25 25 msg %= (extname, section, key)
26 26 ui.develwarn(msg, config='warn-config')
27 27
28 28 knownitems.update(items)
29 29
30 30 class configitem(object):
31 31 """represent a known config item
32 32
33 33 :section: the official config section where to find this item,
34 34 :name: the official name within the section,
35 35 :default: default value for this item,
36 36 :alias: optional list of tuples as alternatives.
37 37 """
38 38
39 39 def __init__(self, section, name, default=None, alias=()):
40 40 self.section = section
41 41 self.name = name
42 42 self.default = default
43 43 self.alias = list(alias)
44 44
45 45 coreitems = {}
46 46
47 47 def _register(configtable, *args, **kwargs):
48 48 item = configitem(*args, **kwargs)
49 49 section = configtable.setdefault(item.section, {})
50 50 if item.name in section:
51 51 msg = "duplicated config item registration for '%s.%s'"
52 52 raise error.ProgrammingError(msg % (item.section, item.name))
53 53 section[item.name] = item
54 54
55 55 # special value for case where the default is derived from other values
56 56 dynamicdefault = object()
57 57
58 58 # Registering actual config items
59 59
60 60 def getitemregister(configtable):
61 61 return functools.partial(_register, configtable)
62 62
63 63 coreconfigitem = getitemregister(coreitems)
64 64
65 65 coreconfigitem('auth', 'cookiefile',
66 66 default=None,
67 67 )
68 68 # bookmarks.pushing: internal hack for discovery
69 69 coreconfigitem('bookmarks', 'pushing',
70 70 default=list,
71 71 )
72 72 # bundle.mainreporoot: internal hack for bundlerepo
73 73 coreconfigitem('bundle', 'mainreporoot',
74 74 default='',
75 75 )
76 76 # bundle.reorder: experimental config
77 77 coreconfigitem('bundle', 'reorder',
78 78 default='auto',
79 79 )
80 80 coreconfigitem('censor', 'policy',
81 81 default='abort',
82 82 )
83 83 coreconfigitem('chgserver', 'idletimeout',
84 84 default=3600,
85 85 )
86 86 coreconfigitem('chgserver', 'skiphash',
87 87 default=False,
88 88 )
89 89 coreconfigitem('cmdserver', 'log',
90 90 default=None,
91 91 )
92 92 coreconfigitem('color', 'mode',
93 93 default='auto',
94 94 )
95 95 coreconfigitem('color', 'pagermode',
96 96 default=dynamicdefault,
97 97 )
98 98 coreconfigitem('commands', 'status.relative',
99 99 default=False,
100 100 )
101 101 coreconfigitem('commands', 'status.skipstates',
102 102 default=[],
103 103 )
104 104 coreconfigitem('commands', 'status.verbose',
105 105 default=False,
106 106 )
107 107 coreconfigitem('commands', 'update.requiredest',
108 108 default=False,
109 109 )
110 110 coreconfigitem('devel', 'all-warnings',
111 111 default=False,
112 112 )
113 113 coreconfigitem('devel', 'bundle2.debug',
114 114 default=False,
115 115 )
116 116 coreconfigitem('devel', 'check-locks',
117 117 default=False,
118 118 )
119 119 coreconfigitem('devel', 'check-relroot',
120 120 default=False,
121 121 )
122 122 coreconfigitem('devel', 'default-date',
123 123 default=None,
124 124 )
125 125 coreconfigitem('devel', 'deprec-warn',
126 126 default=False,
127 127 )
128 128 coreconfigitem('devel', 'disableloaddefaultcerts',
129 129 default=False,
130 130 )
131 131 coreconfigitem('devel', 'legacy.exchange',
132 132 default=list,
133 133 )
134 134 coreconfigitem('devel', 'servercafile',
135 135 default='',
136 136 )
137 137 coreconfigitem('devel', 'serverexactprotocol',
138 138 default='',
139 139 )
140 140 coreconfigitem('devel', 'serverrequirecert',
141 141 default=False,
142 142 )
143 143 coreconfigitem('devel', 'strip-obsmarkers',
144 144 default=True,
145 145 )
146 146 coreconfigitem('email', 'charsets',
147 147 default=list,
148 148 )
149 149 coreconfigitem('email', 'method',
150 150 default='smtp',
151 151 )
152 152 coreconfigitem('experimental', 'bundle-phases',
153 153 default=False,
154 154 )
155 155 coreconfigitem('experimental', 'bundle2-advertise',
156 156 default=True,
157 157 )
158 158 coreconfigitem('experimental', 'bundle2-output-capture',
159 159 default=False,
160 160 )
161 161 coreconfigitem('experimental', 'bundle2.pushback',
162 162 default=False,
163 163 )
164 164 coreconfigitem('experimental', 'bundle2lazylocking',
165 165 default=False,
166 166 )
167 167 coreconfigitem('experimental', 'bundlecomplevel',
168 168 default=None,
169 169 )
170 170 coreconfigitem('experimental', 'changegroup3',
171 171 default=False,
172 172 )
173 173 coreconfigitem('experimental', 'clientcompressionengines',
174 174 default=list,
175 175 )
176 176 coreconfigitem('experimental', 'copytrace',
177 177 default='on',
178 178 )
179 179 coreconfigitem('experimental', 'copytrace.sourcecommitlimit',
180 180 default=100,
181 181 )
182 182 coreconfigitem('experimental', 'crecordtest',
183 183 default=None,
184 184 )
185 185 coreconfigitem('experimental', 'editortmpinhg',
186 186 default=False,
187 187 )
188 188 coreconfigitem('experimental', 'stabilization',
189 189 default=list,
190 190 alias=[('experimental', 'evolution')],
191 191 )
192 192 coreconfigitem('experimental', 'stabilization.bundle-obsmarker',
193 193 default=False,
194 194 alias=[('experimental', 'evolution.bundle-obsmarker')],
195 195 )
196 196 coreconfigitem('experimental', 'stabilization.track-operation',
197 197 default=True,
198 198 alias=[('experimental', 'evolution.track-operation')]
199 199 )
200 200 coreconfigitem('experimental', 'exportableenviron',
201 201 default=list,
202 202 )
203 203 coreconfigitem('experimental', 'extendedheader.index',
204 204 default=None,
205 205 )
206 206 coreconfigitem('experimental', 'extendedheader.similarity',
207 207 default=False,
208 208 )
209 209 coreconfigitem('experimental', 'format.compression',
210 210 default='zlib',
211 211 )
212 212 coreconfigitem('experimental', 'graphshorten',
213 213 default=False,
214 214 )
215 215 coreconfigitem('experimental', 'hook-track-tags',
216 216 default=False,
217 217 )
218 218 coreconfigitem('experimental', 'httppostargs',
219 219 default=False,
220 220 )
221 221 coreconfigitem('experimental', 'manifestv2',
222 222 default=False,
223 223 )
224 224 coreconfigitem('experimental', 'mergedriver',
225 225 default=None,
226 226 )
227 227 coreconfigitem('experimental', 'obsmarkers-exchange-debug',
228 228 default=False,
229 229 )
230 230 coreconfigitem('experimental', 'rebase.multidest',
231 231 default=False,
232 232 )
233 233 coreconfigitem('experimental', 'revertalternateinteractivemode',
234 234 default=True,
235 235 )
236 236 coreconfigitem('experimental', 'revlogv2',
237 237 default=None,
238 238 )
239 239 coreconfigitem('experimental', 'spacemovesdown',
240 240 default=False,
241 241 )
242 242 coreconfigitem('experimental', 'treemanifest',
243 243 default=False,
244 244 )
245 245 coreconfigitem('experimental', 'updatecheck',
246 246 default=None,
247 247 )
248 248 coreconfigitem('format', 'aggressivemergedeltas',
249 249 default=False,
250 250 )
251 251 coreconfigitem('format', 'chunkcachesize',
252 252 default=None,
253 253 )
254 254 coreconfigitem('format', 'dotencode',
255 255 default=True,
256 256 )
257 257 coreconfigitem('format', 'generaldelta',
258 258 default=False,
259 259 )
260 260 coreconfigitem('format', 'manifestcachesize',
261 261 default=None,
262 262 )
263 263 coreconfigitem('format', 'maxchainlen',
264 264 default=None,
265 265 )
266 266 coreconfigitem('format', 'obsstore-version',
267 267 default=None,
268 268 )
269 269 coreconfigitem('format', 'usefncache',
270 270 default=True,
271 271 )
272 272 coreconfigitem('format', 'usegeneraldelta',
273 273 default=True,
274 274 )
275 275 coreconfigitem('format', 'usestore',
276 276 default=True,
277 277 )
278 278 coreconfigitem('hostsecurity', 'ciphers',
279 279 default=None,
280 280 )
281 281 coreconfigitem('hostsecurity', 'disabletls10warning',
282 282 default=False,
283 283 )
284 284 coreconfigitem('http_proxy', 'always',
285 285 default=False,
286 286 )
287 287 coreconfigitem('http_proxy', 'host',
288 288 default=None,
289 289 )
290 290 coreconfigitem('http_proxy', 'no',
291 291 default=list,
292 292 )
293 293 coreconfigitem('http_proxy', 'passwd',
294 294 default=None,
295 295 )
296 296 coreconfigitem('http_proxy', 'user',
297 297 default=None,
298 298 )
299 299 coreconfigitem('merge', 'followcopies',
300 300 default=True,
301 301 )
302 302 coreconfigitem('pager', 'ignore',
303 303 default=list,
304 304 )
305 305 coreconfigitem('patch', 'eol',
306 306 default='strict',
307 307 )
308 308 coreconfigitem('patch', 'fuzz',
309 309 default=2,
310 310 )
311 311 coreconfigitem('paths', 'default',
312 312 default=None,
313 313 )
314 314 coreconfigitem('paths', 'default-push',
315 315 default=None,
316 316 )
317 317 coreconfigitem('phases', 'checksubrepos',
318 318 default='follow',
319 319 )
320 320 coreconfigitem('phases', 'publish',
321 321 default=True,
322 322 )
323 323 coreconfigitem('profiling', 'enabled',
324 324 default=False,
325 325 )
326 326 coreconfigitem('profiling', 'format',
327 327 default='text',
328 328 )
329 329 coreconfigitem('profiling', 'freq',
330 330 default=1000,
331 331 )
332 332 coreconfigitem('profiling', 'limit',
333 333 default=30,
334 334 )
335 335 coreconfigitem('profiling', 'nested',
336 336 default=0,
337 337 )
338 338 coreconfigitem('profiling', 'sort',
339 339 default='inlinetime',
340 340 )
341 341 coreconfigitem('profiling', 'statformat',
342 342 default='hotpath',
343 343 )
344 344 coreconfigitem('progress', 'assume-tty',
345 345 default=False,
346 346 )
347 347 coreconfigitem('progress', 'changedelay',
348 348 default=1,
349 349 )
350 350 coreconfigitem('progress', 'clear-complete',
351 351 default=True,
352 352 )
353 353 coreconfigitem('progress', 'debug',
354 354 default=False,
355 355 )
356 356 coreconfigitem('progress', 'delay',
357 357 default=3,
358 358 )
359 359 coreconfigitem('progress', 'disable',
360 360 default=False,
361 361 )
362 coreconfigitem('progress', 'estimate',
363 default=2,
364 )
365 362 coreconfigitem('progress', 'refresh',
366 363 default=0.1,
367 364 )
368 365 coreconfigitem('progress', 'width',
369 366 default=dynamicdefault,
370 367 )
371 368 coreconfigitem('push', 'pushvars.server',
372 369 default=False,
373 370 )
374 371 coreconfigitem('server', 'bundle1',
375 372 default=True,
376 373 )
377 374 coreconfigitem('server', 'bundle1gd',
378 375 default=None,
379 376 )
380 377 coreconfigitem('server', 'compressionengines',
381 378 default=list,
382 379 )
383 380 coreconfigitem('server', 'concurrent-push-mode',
384 381 default='strict',
385 382 )
386 383 coreconfigitem('server', 'disablefullbundle',
387 384 default=False,
388 385 )
389 386 coreconfigitem('server', 'maxhttpheaderlen',
390 387 default=1024,
391 388 )
392 389 coreconfigitem('server', 'preferuncompressed',
393 390 default=False,
394 391 )
395 392 coreconfigitem('server', 'uncompressed',
396 393 default=True,
397 394 )
398 395 coreconfigitem('server', 'uncompressedallowsecret',
399 396 default=False,
400 397 )
401 398 coreconfigitem('server', 'validate',
402 399 default=False,
403 400 )
404 401 coreconfigitem('server', 'zliblevel',
405 402 default=-1,
406 403 )
407 404 coreconfigitem('smtp', 'host',
408 405 default=None,
409 406 )
410 407 coreconfigitem('smtp', 'local_hostname',
411 408 default=None,
412 409 )
413 410 coreconfigitem('smtp', 'password',
414 411 default=None,
415 412 )
416 413 coreconfigitem('smtp', 'tls',
417 414 default='none',
418 415 )
419 416 coreconfigitem('smtp', 'username',
420 417 default=None,
421 418 )
422 419 coreconfigitem('sparse', 'missingwarning',
423 420 default=True,
424 421 )
425 422 coreconfigitem('trusted', 'groups',
426 423 default=list,
427 424 )
428 425 coreconfigitem('trusted', 'users',
429 426 default=list,
430 427 )
431 428 coreconfigitem('ui', '_usedassubrepo',
432 429 default=False,
433 430 )
434 431 coreconfigitem('ui', 'allowemptycommit',
435 432 default=False,
436 433 )
437 434 coreconfigitem('ui', 'archivemeta',
438 435 default=True,
439 436 )
440 437 coreconfigitem('ui', 'askusername',
441 438 default=False,
442 439 )
443 440 coreconfigitem('ui', 'clonebundlefallback',
444 441 default=False,
445 442 )
446 443 coreconfigitem('ui', 'clonebundleprefers',
447 444 default=list,
448 445 )
449 446 coreconfigitem('ui', 'clonebundles',
450 447 default=True,
451 448 )
452 449 coreconfigitem('ui', 'color',
453 450 default='auto',
454 451 )
455 452 coreconfigitem('ui', 'commitsubrepos',
456 453 default=False,
457 454 )
458 455 coreconfigitem('ui', 'debug',
459 456 default=False,
460 457 )
461 458 coreconfigitem('ui', 'debugger',
462 459 default=None,
463 460 )
464 461 coreconfigitem('ui', 'fallbackencoding',
465 462 default=None,
466 463 )
467 464 coreconfigitem('ui', 'forcecwd',
468 465 default=None,
469 466 )
470 467 coreconfigitem('ui', 'forcemerge',
471 468 default=None,
472 469 )
473 470 coreconfigitem('ui', 'formatdebug',
474 471 default=False,
475 472 )
476 473 coreconfigitem('ui', 'formatjson',
477 474 default=False,
478 475 )
479 476 coreconfigitem('ui', 'formatted',
480 477 default=None,
481 478 )
482 479 coreconfigitem('ui', 'graphnodetemplate',
483 480 default=None,
484 481 )
485 482 coreconfigitem('ui', 'http2debuglevel',
486 483 default=None,
487 484 )
488 485 coreconfigitem('ui', 'interactive',
489 486 default=None,
490 487 )
491 488 coreconfigitem('ui', 'interface',
492 489 default=None,
493 490 )
494 491 coreconfigitem('ui', 'logblockedtimes',
495 492 default=False,
496 493 )
497 494 coreconfigitem('ui', 'logtemplate',
498 495 default=None,
499 496 )
500 497 coreconfigitem('ui', 'merge',
501 498 default=None,
502 499 )
503 500 coreconfigitem('ui', 'mergemarkers',
504 501 default='basic',
505 502 )
506 503 coreconfigitem('ui', 'mergemarkertemplate',
507 504 default=('{node|short} '
508 505 '{ifeq(tags, "tip", "", '
509 506 'ifeq(tags, "", "", "{tags} "))}'
510 507 '{if(bookmarks, "{bookmarks} ")}'
511 508 '{ifeq(branch, "default", "", "{branch} ")}'
512 509 '- {author|user}: {desc|firstline}')
513 510 )
514 511 coreconfigitem('ui', 'nontty',
515 512 default=False,
516 513 )
517 514 coreconfigitem('ui', 'origbackuppath',
518 515 default=None,
519 516 )
520 517 coreconfigitem('ui', 'paginate',
521 518 default=True,
522 519 )
523 520 coreconfigitem('ui', 'patch',
524 521 default=None,
525 522 )
526 523 coreconfigitem('ui', 'portablefilenames',
527 524 default='warn',
528 525 )
529 526 coreconfigitem('ui', 'promptecho',
530 527 default=False,
531 528 )
532 529 coreconfigitem('ui', 'quiet',
533 530 default=False,
534 531 )
535 532 coreconfigitem('ui', 'quietbookmarkmove',
536 533 default=False,
537 534 )
538 535 coreconfigitem('ui', 'remotecmd',
539 536 default='hg',
540 537 )
541 538 coreconfigitem('ui', 'report_untrusted',
542 539 default=True,
543 540 )
544 541 coreconfigitem('ui', 'rollback',
545 542 default=True,
546 543 )
547 544 coreconfigitem('ui', 'slash',
548 545 default=False,
549 546 )
550 547 coreconfigitem('ui', 'ssh',
551 548 default='ssh',
552 549 )
553 550 coreconfigitem('ui', 'statuscopies',
554 551 default=False,
555 552 )
556 553 coreconfigitem('ui', 'strict',
557 554 default=False,
558 555 )
559 556 coreconfigitem('ui', 'style',
560 557 default='',
561 558 )
562 559 coreconfigitem('ui', 'supportcontact',
563 560 default=None,
564 561 )
565 562 coreconfigitem('ui', 'textwidth',
566 563 default=78,
567 564 )
568 565 coreconfigitem('ui', 'timeout',
569 566 default='600',
570 567 )
571 568 coreconfigitem('ui', 'traceback',
572 569 default=False,
573 570 )
574 571 coreconfigitem('ui', 'tweakdefaults',
575 572 default=False,
576 573 )
577 574 coreconfigitem('ui', 'usehttp2',
578 575 default=False,
579 576 )
580 577 coreconfigitem('ui', 'username',
581 578 alias=[('ui', 'user')]
582 579 )
583 580 coreconfigitem('ui', 'verbose',
584 581 default=False,
585 582 )
586 583 coreconfigitem('verify', 'skipflags',
587 584 default=None,
588 585 )
589 586 coreconfigitem('web', 'accesslog',
590 587 default='-',
591 588 )
592 589 coreconfigitem('web', 'address',
593 590 default='',
594 591 )
595 592 coreconfigitem('web', 'allow_archive',
596 593 default=list,
597 594 )
598 595 coreconfigitem('web', 'allow_read',
599 596 default=list,
600 597 )
601 598 coreconfigitem('web', 'baseurl',
602 599 default=None,
603 600 )
604 601 coreconfigitem('web', 'cacerts',
605 602 default=None,
606 603 )
607 604 coreconfigitem('web', 'certificate',
608 605 default=None,
609 606 )
610 607 coreconfigitem('web', 'collapse',
611 608 default=False,
612 609 )
613 610 coreconfigitem('web', 'csp',
614 611 default=None,
615 612 )
616 613 coreconfigitem('web', 'deny_read',
617 614 default=list,
618 615 )
619 616 coreconfigitem('web', 'descend',
620 617 default=True,
621 618 )
622 619 coreconfigitem('web', 'description',
623 620 default="",
624 621 )
625 622 coreconfigitem('web', 'encoding',
626 623 default=lambda: encoding.encoding,
627 624 )
628 625 coreconfigitem('web', 'errorlog',
629 626 default='-',
630 627 )
631 628 coreconfigitem('web', 'ipv6',
632 629 default=False,
633 630 )
634 631 coreconfigitem('web', 'port',
635 632 default=8000,
636 633 )
637 634 coreconfigitem('web', 'prefix',
638 635 default='',
639 636 )
640 637 coreconfigitem('web', 'refreshinterval',
641 638 default=20,
642 639 )
643 640 coreconfigitem('web', 'stripes',
644 641 default=1,
645 642 )
646 643 coreconfigitem('web', 'style',
647 644 default='paper',
648 645 )
649 646 coreconfigitem('web', 'templates',
650 647 default=None,
651 648 )
652 649 coreconfigitem('worker', 'backgroundclose',
653 650 default=dynamicdefault,
654 651 )
655 652 # Windows defaults to a limit of 512 open files. A buffer of 128
656 653 # should give us enough headway.
657 654 coreconfigitem('worker', 'backgroundclosemaxqueue',
658 655 default=384,
659 656 )
660 657 coreconfigitem('worker', 'backgroundcloseminfilecount',
661 658 default=2048,
662 659 )
663 660 coreconfigitem('worker', 'backgroundclosethreadcount',
664 661 default=4,
665 662 )
666 663 coreconfigitem('worker', 'numcpus',
667 664 default=None,
668 665 )
@@ -1,280 +1,276
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 104 self.order = self.ui.configlist(
105 105 'progress', 'format',
106 106 default=['topic', 'bar', 'number', 'estimate'])
107 107
108 108 def show(self, now, topic, pos, item, unit, total):
109 109 if not shouldprint(self.ui):
110 110 return
111 111 termwidth = self.width()
112 112 self.printed = True
113 113 head = ''
114 114 needprogress = False
115 115 tail = ''
116 116 for indicator in self.order:
117 117 add = ''
118 118 if indicator == 'topic':
119 119 add = topic
120 120 elif indicator == 'number':
121 121 if total:
122 122 add = ('% ' + str(len(str(total))) +
123 123 's/%s') % (pos, total)
124 124 else:
125 125 add = str(pos)
126 126 elif indicator.startswith('item') and item:
127 127 slice = 'end'
128 128 if '-' in indicator:
129 129 wid = int(indicator.split('-')[1])
130 130 elif '+' in indicator:
131 131 slice = 'beginning'
132 132 wid = int(indicator.split('+')[1])
133 133 else:
134 134 wid = 20
135 135 if slice == 'end':
136 136 add = encoding.trim(item, wid, leftside=True)
137 137 else:
138 138 add = encoding.trim(item, wid)
139 139 add += (wid - encoding.colwidth(add)) * ' '
140 140 elif indicator == 'bar':
141 141 add = ''
142 142 needprogress = True
143 143 elif indicator == 'unit' and unit:
144 144 add = unit
145 145 elif indicator == 'estimate':
146 146 add = self.estimate(topic, pos, total, now)
147 147 elif indicator == 'speed':
148 148 add = self.speed(topic, pos, unit, now)
149 149 if not needprogress:
150 150 head = spacejoin(head, add)
151 151 else:
152 152 tail = spacejoin(tail, add)
153 153 if needprogress:
154 154 used = 0
155 155 if head:
156 156 used += encoding.colwidth(head) + 1
157 157 if tail:
158 158 used += encoding.colwidth(tail) + 1
159 159 progwidth = termwidth - used - 3
160 160 if total and pos <= total:
161 161 amt = pos * progwidth // total
162 162 bar = '=' * (amt - 1)
163 163 if amt > 0:
164 164 bar += '>'
165 165 bar += ' ' * (progwidth - amt)
166 166 else:
167 167 progwidth -= 3
168 168 self.indetcount += 1
169 169 # mod the count by twice the width so we can make the
170 170 # cursor bounce between the right and left sides
171 171 amt = self.indetcount % (2 * progwidth)
172 172 amt -= progwidth
173 173 bar = (' ' * int(progwidth - abs(amt)) + '<=>' +
174 174 ' ' * int(abs(amt)))
175 175 prog = ''.join(('[', bar , ']'))
176 176 out = spacejoin(head, prog, tail)
177 177 else:
178 178 out = spacejoin(head, tail)
179 179 self._writeerr('\r' + encoding.trim(out, termwidth))
180 180 self.lasttopic = topic
181 181 self._flusherr()
182 182
183 183 def clear(self):
184 184 if not self.printed or not self.lastprint or not shouldprint(self.ui):
185 185 return
186 186 self._writeerr('\r%s\r' % (' ' * self.width()))
187 187 if self.printed:
188 188 # force immediate re-paint of progress bar
189 189 self.lastprint = 0
190 190
191 191 def complete(self):
192 192 if not shouldprint(self.ui):
193 193 return
194 194 if self.ui.configbool('progress', 'clear-complete'):
195 195 self.clear()
196 196 else:
197 197 self._writeerr('\n')
198 198 self._flusherr()
199 199
200 200 def _flusherr(self):
201 201 _eintrretry(self.ui.ferr.flush)
202 202
203 203 def _writeerr(self, msg):
204 204 _eintrretry(self.ui.ferr.write, msg)
205 205
206 206 def width(self):
207 207 tw = self.ui.termwidth()
208 208 return min(int(self.ui.config('progress', 'width', default=tw)), tw)
209 209
210 210 def estimate(self, topic, pos, total, now):
211 211 if total is None:
212 212 return ''
213 213 initialpos = self.startvals[topic]
214 214 target = total - initialpos
215 215 delta = pos - initialpos
216 216 if delta > 0:
217 217 elapsed = now - self.starttimes[topic]
218 # experimental config: progress.estimate
219 if elapsed > float(
220 self.ui.config('progress', 'estimate')):
221 218 seconds = (elapsed * (target - delta)) // delta + 1
222 219 return fmtremaining(seconds)
223 220 return ''
224 221
225 222 def speed(self, topic, pos, unit, now):
226 223 initialpos = self.startvals[topic]
227 224 delta = pos - initialpos
228 225 elapsed = now - self.starttimes[topic]
229 if elapsed > float(
230 self.ui.config('progress', 'estimate')):
226 if elapsed > 0:
231 227 return _('%d %s/sec') % (delta / elapsed, unit)
232 228 return ''
233 229
234 230 def _oktoprint(self, now):
235 231 '''Check if conditions are met to print - e.g. changedelay elapsed'''
236 232 if (self.lasttopic is None # first time we printed
237 233 # not a topic change
238 234 or self.curtopic == self.lasttopic
239 235 # it's been long enough we should print anyway
240 236 or now - self.lastprint >= self.changedelay):
241 237 return True
242 238 else:
243 239 return False
244 240
245 241 def progress(self, topic, pos, item='', unit='', total=None):
246 242 now = time.time()
247 243 self._refreshlock.acquire()
248 244 try:
249 245 if pos is None:
250 246 self.starttimes.pop(topic, None)
251 247 self.startvals.pop(topic, None)
252 248 self.topicstates.pop(topic, None)
253 249 # reset the progress bar if this is the outermost topic
254 250 if self.topics and self.topics[0] == topic and self.printed:
255 251 self.complete()
256 252 self.resetstate()
257 253 # truncate the list of topics assuming all topics within
258 254 # this one are also closed
259 255 if topic in self.topics:
260 256 self.topics = self.topics[:self.topics.index(topic)]
261 257 # reset the last topic to the one we just unwound to,
262 258 # so that higher-level topics will be stickier than
263 259 # lower-level topics
264 260 if self.topics:
265 261 self.lasttopic = self.topics[-1]
266 262 else:
267 263 self.lasttopic = None
268 264 else:
269 265 if topic not in self.topics:
270 266 self.starttimes[topic] = now
271 267 self.startvals[topic] = pos
272 268 self.topics.append(topic)
273 269 self.topicstates[topic] = pos, item, unit, total
274 270 self.curtopic = topic
275 271 if now - self.lastprint >= self.refresh and self.topics:
276 272 if self._oktoprint(now):
277 273 self.lastprint = now
278 274 self.show(now, topic, *self.topicstates[topic])
279 275 finally:
280 276 self._refreshlock.release()
General Comments 0
You need to be logged in to leave comments. Login now