Rev 3940: (mbp) transport-based progress bars in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Thu Jan 15 07:34:23 GMT 2009
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3940
revision-id: pqm at pqm.ubuntu.com-20090115073416-vnzvkab4dfesetj0
parent: pqm at pqm.ubuntu.com-20090115062848-vl9tlzwnawaqht01
parent: mbp at sourcefrog.net-20090115064409-ual02s892v27bq5o
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-01-15 07:34:16 +0000
message:
(mbp) transport-based progress bars
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/commands.py bzr.py-20050309040720-d10f4714595cf8c3
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/blackbox/test_upgrade.py test_upgrade.py-20060120060132-b41e5ed2f886ad28
bzrlib/tests/test_sftp_transport.py testsftp.py-20051027032739-247570325fec7e7e
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.7.17
revision-id: mbp at sourcefrog.net-20090115064409-ual02s892v27bq5o
parent: mbp at sourcefrog.net-20090115051249-dwwq2byltadxi6s8
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Thu 2009-01-15 17:44:09 +1100
message:
test_ui should not expect warnings from ProgressBar.finished
modified:
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
------------------------------------------------------------
revno: 3882.7.16
revision-id: mbp at sourcefrog.net-20090115051249-dwwq2byltadxi6s8
parent: mbp at sourcefrog.net-20090115032155-vaxa3k8pdeh15r4z
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Thu 2009-01-15 16:12:49 +1100
message:
Update SFTP tests to accommodate progress reporting
modified:
bzrlib/tests/test_sftp_transport.py testsftp.py-20051027032739-247570325fec7e7e
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
------------------------------------------------------------
revno: 3882.7.15
revision-id: mbp at sourcefrog.net-20090115032155-vaxa3k8pdeh15r4z
parent: mbp at sourcefrog.net-20090113051626-0d5q6luqdoyx4xaf
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Thu 2009-01-15 14:21:55 +1100
message:
Remove Robey's copyright as he assigned to Canonical
modified:
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
------------------------------------------------------------
revno: 3882.7.14
revision-id: mbp at sourcefrog.net-20090113051626-0d5q6luqdoyx4xaf
parent: mbp at sourcefrog.net-20090113050727-r0uw27cvei8tyvh8
parent: pqm at pqm.ubuntu.com-20090112185737-d6kwagahecadwfce
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2009-01-13 16:16:26 +1100
message:
Fix recommend_upgrade ui and merge trunk
added:
bzrlib/plugins/netrc_credential_store/ netrc_credential_sto-20081006090354-oaoid1olhgk8vevm-1
bzrlib/plugins/netrc_credential_store/__init__.py __init__.py-20081006090402-hd75m8kcrrm0vlz1-1
bzrlib/plugins/netrc_credential_store/tests/ tests-20081006090406-6mddz8j10pux993e-1
bzrlib/plugins/netrc_credential_store/tests/__init__.py __init__.py-20081006090411-vytweyz6sun61d4q-1
bzrlib/plugins/netrc_credential_store/tests/test_netrc.py test_netrc.py-20081006090414-vm3or4tz6c9wk2oi-1
bzrlib/tests/https_server.py https_server.py-20071121173708-aj8zczi0ziwbwz21-1
bzrlib/tests/ssl_certs/ ssl_certs-20071124141654-dc9za9nho2gmzbri-1
bzrlib/tests/ssl_certs/__init__.py __init__.py-20071124141703-j5hr254lm287lyut-8
bzrlib/tests/ssl_certs/ca.crt ca.crt-20071124141703-j5hr254lm287lyut-7
bzrlib/tests/ssl_certs/ca.key ca.key-20071124141703-j5hr254lm287lyut-6
bzrlib/tests/ssl_certs/create_ssls.py create_ssls.py-20071124141703-j5hr254lm287lyut-5
bzrlib/tests/ssl_certs/server.crt server.crt-20071124141703-j5hr254lm287lyut-4
bzrlib/tests/ssl_certs/server.csr server.csr-20071124141703-j5hr254lm287lyut-3
bzrlib/tests/ssl_certs/server_with_pass.key server_with_pass.key-20071124141703-j5hr254lm287lyut-2
bzrlib/tests/ssl_certs/server_without_pass.key server_without_pass.-20071124141703-j5hr254lm287lyut-1
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/config.py config.py-20051011043216-070c74f4e9e338e8
bzrlib/diff.py diff.py-20050309040759-26944fbbf2ebbf36
bzrlib/dirstate.py dirstate.py-20060728012006-d6mvoihjb3je9peu-1
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/help_topics/en/configuration.txt configuration.txt-20060314161707-868350809502af01
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/log.py log.py-20050505065812-c40ce11702fe5fb1
bzrlib/mail_client.py mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/patiencediff.py patiencediff.py-20070721205536-jz8gaykeb7xtampk-1
bzrlib/push.py push.py-20080606021927-5fe39050e8xne9un-1
bzrlib/smart/medium.py medium.py-20061103051856-rgu2huy59fkz902q-1
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
bzrlib/tests/branch_implementations/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
bzrlib/tests/commands/test_push.py test_push.py-20070525122003-gc1ob0ea0nueoqgj-1
bzrlib/tests/http_server.py httpserver.py-20061012142527-m1yxdj1xazsf8d7s-1
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
bzrlib/tests/test_config.py testconfig.py-20051011041908-742d0c15d8d8c8eb
bzrlib/tests/test_diff.py testdiff.py-20050727164403-d1a3496ebb12e339
bzrlib/tests/test_errors.py test_errors.py-20060210110251-41aba2deddf936a8
bzrlib/tests/test_http.py testhttp.py-20051018020158-b2eef6e867c514d9
bzrlib/tests/test_log.py testlog.py-20050728115707-1a514809d7d49309
bzrlib/tests/test_mail_client.py test_mail_client.py-20070809192806-vuxt3t19srtpjpdn-2
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
bzrlib/tests/test_plugins.py plugins.py-20050622075746-32002b55e5e943e9
bzrlib/tests/workingtree_implementations/test_move.py test_move.py-20070225171927-mohn2vqj5fx7edc6-1
bzrlib/trace.py trace.py-20050309040759-c8ed824bdcd4748a
bzrlib/transport/ftp/__init__.py ftp.py-20051116161804-58dc9506548c2a53
bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
bzrlib/transport/http/_urllib.py _urlgrabber.py-20060113083826-0bbf7d992fbf090c
bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
bzrlib/transport/http/ca_bundle.py ca_bundle.py-20070226091335-84kb1xg1r2jjf858-1
doc/developers/authentication-ring.txt authring.txt-20070718200437-q5tdik0ne6lor86d-1
tools/win32/build_release.py build_release.py-20081105204355-2ghh5cv01v1x4rzz-1
------------------------------------------------------------
revno: 3882.7.13
revision-id: mbp at sourcefrog.net-20090113050727-r0uw27cvei8tyvh8
parent: mbp at sourcefrog.net-20081224073737-1pm721uhv3077qd0
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2009-01-13 16:07:27 +1100
message:
Don't mask out recommend_upgrade in CLIUIFactory
modified:
bzrlib/tests/blackbox/test_upgrade.py test_upgrade.py-20060120060132-b41e5ed2f886ad28
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
------------------------------------------------------------
revno: 3882.7.12
revision-id: mbp at sourcefrog.net-20081224073737-1pm721uhv3077qd0
parent: mbp at sourcefrog.net-20081224070720-ptodndbmje6uy5ej
parent: pqm at pqm.ubuntu.com-20081224050842-15xix09apawzgs05
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Wed 2008-12-24 18:37:37 +1100
message:
merge news
added:
bzrlib/_chunks_to_lines_py.py _chunks_to_lines_py.-20081211024848-6uc3mtuje8j14l60-1
bzrlib/_chunks_to_lines_pyx.pyx _chunks_to_lines_pyx-20081211021736-op7n8vrxgrd8snfi-1
bzrlib/fifo_cache.py fifo_cache.py-20081209212307-31ffjwvteyvmydnf-1
bzrlib/tests/blackbox/test_shelve.py test_ls_shelf.py-20081202053526-thlo8yt0pi1cgor1-1
bzrlib/tests/per_repository/test_add_inventory_by_delta.py test_add_inventory_d-20081013002626-rut81igtlqb4590z-1
bzrlib/tests/test__chunks_to_lines.py test__chunks_to_line-20081211024848-6uc3mtuje8j14l60-2
bzrlib/tests/test_fifo_cache.py test_fifo_cache.py-20081209212307-31ffjwvteyvmydnf-2
modified:
.bzrignore bzrignore-20050311232317-81f7b71efa2db11a
Makefile Makefile-20050805140406-d96e3498bb61c5bb
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/__init__.py __init__.py-20050309040759-33e65acf91bbcd5d
bzrlib/_dirstate_helpers_c.h _dirstate_helpers_c.-20070802205935-hqo9yzuzjix271dd-1
bzrlib/atomicfile.py atomicfile.py-20050509044450-dbd24e6c564f7c66
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/builtins.py builtins.py-20050830033751-fc01482b9ca23183
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/commit.py commit.py-20050511101309-79ec1a0168e0e825
bzrlib/delta.py delta.py-20050729221636-54cf14ef94783d0a
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/foreign.py foreign.py-20081112170002-olsxmandkk8qyfuq-1
bzrlib/graph.py graph_walker.py-20070525030359-y852guab65d4wtn0-1
bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
bzrlib/inventory.py inventory.py-20050309040759-6648b84ca2005b37
bzrlib/knit.py knit.py-20051212171256-f056ac8f0fbe1bd9
bzrlib/log.py log.py-20050505065812-c40ce11702fe5fb1
bzrlib/lru_cache.py lru_cache.py-20070119165515-tlw203kuwh0id5gv-1
bzrlib/merge.py merge.py-20050513021216-953b65a438527106
bzrlib/msgeditor.py msgeditor.py-20050901111708-ef6d8de98f5d8f2f
bzrlib/osutils.py osutils.py-20050309040759-eeaff12fbf77ac86
bzrlib/push.py push.py-20080606021927-5fe39050e8xne9un-1
bzrlib/registry.py lazy_factory.py-20060809213415-2gfvqadtvdn0phtg-1
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repofmt/pack_repo.py pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/shelf.py prepare_shelf.py-20081005181341-n74qe6gu1e65ad4v-1
bzrlib/shelf_ui.py shelver.py-20081005210102-33worgzwrtdw0yrm-1
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
bzrlib/tests/blackbox/test_ls.py test_ls.py-20060712232047-0jraqpecwngee12y-1
bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
bzrlib/tests/blackbox/test_revision_info.py test_revision_info.py-20050917162600-21dab3877aa348d7
bzrlib/tests/blackbox/test_tags.py test_tags.py-20070116132048-5h4qak2cm22jlb9e-1
bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
bzrlib/tests/interrepository_implementations/__init__.py __init__.py-20060220054744-baf49a1f88f17b1a
bzrlib/tests/per_repository/__init__.py __init__.py-20060131092037-9564957a7d4a841b
bzrlib/tests/per_repository/test_add_fallback_repository.py test_add_fallback_re-20080215040003-8w9n4ck9uqdxj18m-1
bzrlib/tests/per_repository/test_commit_builder.py test_commit_builder.py-20060606110838-76e3ra5slucqus81-1
bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
bzrlib/tests/test_bzrdir.py test_bzrdir.py-20060131065654-deba40eef51cf220
bzrlib/tests/test_graph.py test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
bzrlib/tests/test_http.py testhttp.py-20051018020158-b2eef6e867c514d9
bzrlib/tests/test_info.py test_info.py-20070320150933-m0xxm1g7xi9v6noe-1
bzrlib/tests/test_knit.py test_knit.py-20051212171302-95d4c00dd5f11f2b
bzrlib/tests/test_lru_cache.py test_lru_cache.py-20070119165535-hph6rk4h9rzy4180-1
bzrlib/tests/test_msgeditor.py test_msgeditor.py-20051202041359-920315ec6011ee51
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
bzrlib/tests/test_revisionspec.py testrevisionnamespaces.py-20050711050225-8b4af89e6b1efe84
bzrlib/tests/test_selftest.py test_selftest.py-20051202044319-c110a115d8c0456a
bzrlib/tests/test_shelf.py test_prepare_shelf.p-20081005181341-n74qe6gu1e65ad4v-2
bzrlib/tests/test_smart_transport.py test_ssh_transport.py-20060608202016-c25gvf1ob7ypbus6-2
bzrlib/tests/test_source.py test_source.py-20051207061333-a58dea6abecc030d
bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
bzrlib/tests/tree_implementations/__init__.py __init__.py-20060717075546-420s7b0bj9hzeowi-2
bzrlib/tests/workingtree_implementations/test_add.py test_add.py-20070226165239-4vo178spkrnhavc7-1
bzrlib/tests/workingtree_implementations/test_basis_inventory.py test_basis_inventory.py-20051218151655-3650468941091309
bzrlib/tests/workingtree_implementations/test_move.py test_move.py-20070225171927-mohn2vqj5fx7edc6-1
bzrlib/tests/workingtree_implementations/test_rename_one.py test_rename_one.py-20070226161242-2d8ibdedl700jgio-1
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
bzrlib/transport/decorator.py decorator.py-20060402223305-e913a0f25319ab42
bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
bzrlib/transport/http/_pycurl.py pycurlhttp.py-20060110060940-4e2a705911af77a6
bzrlib/transport/http/_urllib.py _urlgrabber.py-20060113083826-0bbf7d992fbf090c
bzrlib/transport/remote.py ssh.py-20060608202016-c25gvf1ob7ypbus6-1
bzrlib/tree.py tree.py-20050309040759-9d5f2496be663e77
bzrlib/versionedfile.py versionedfile.py-20060222045106-5039c71ee3b65490
bzrlib/weave.py knit.py-20050627021749-759c29984154256b
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
bzrlib/workingtree_4.py workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
bzrlib/xml4.py xml4.py-20050916091259-db5ab55e7e6ca324
bzrlib/xml5.py xml5.py-20080328030717-t9guwinq8hom0ar3-1
bzrlib/xml7.py xml7.py-20061029182747-d5tiiny21bvrd2jj-1
bzrlib/xml8.py xml5.py-20050907032657-aac8f960815b66b1
bzrlib/xml_serializer.py xml.py-20050309040759-57d51586fdec365d
doc/developers/HACKING.txt HACKING-20050805200004-2a5dc975d870f78c
doc/en/user-guide/organizing_branches.txt organizing_branches.-20071123154453-dk2mjhrg1vpjm5w2-3
doc/en/user-guide/publishing_a_branch.txt publishing_a_branch.-20071123055134-k5x4ekduci2lbn36-2
doc/en/user-guide/reusing_a_checkout.txt reusing_a_checkout.t-20071123055134-k5x4ekduci2lbn36-3
doc/en/user-guide/svn_plugin.txt svn_plugin.txt-20080509065016-cjc90f46407vi9a0-2
doc/en/user-guide/using_checkouts.txt using_checkouts.txt-20071123055134-k5x4ekduci2lbn36-4
setup.py setup.py-20050314065409-02f8a0a6e3f9bc70
tools/win32/build_release.py build_release.py-20081105204355-2ghh5cv01v1x4rzz-1
------------------------------------------------------------
revno: 3882.7.11
revision-id: mbp at sourcefrog.net-20081224070720-ptodndbmje6uy5ej
parent: mbp at sourcefrog.net-20081224070433-6trk2e9btcx45o6s
parent: mbp at sourcefrog.net-20081217082831-gfro2xbtou9w1bnd
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Wed 2008-12-24 18:07:20 +1100
message:
Merge other progress work
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/commands.py bzr.py-20050309040720-d10f4714595cf8c3
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.8.14
revision-id: mbp at sourcefrog.net-20081217082831-gfro2xbtou9w1bnd
parent: mbp at sourcefrog.net-20081217082742-8ezdb3qvhx7rcpuq
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Wed 2008-12-17 19:28:31 +1100
message:
note progress apis have changed
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
------------------------------------------------------------
revno: 3882.8.13
revision-id: mbp at sourcefrog.net-20081217082742-8ezdb3qvhx7rcpuq
parent: mbp at sourcefrog.net-20081217081814-qxpip6fd8f3ofkgh
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Wed 2008-12-17 19:27:42 +1100
message:
update news
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
------------------------------------------------------------
revno: 3882.8.12
revision-id: mbp at sourcefrog.net-20081217081814-qxpip6fd8f3ofkgh
parent: mbp at sourcefrog.net-20081216075629-zhgjzxgoh32453tu
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Wed 2008-12-17 19:18:14 +1100
message:
Give a warning, not an error, if a progress bar is not finished in order
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
------------------------------------------------------------
revno: 3882.8.11
revision-id: mbp at sourcefrog.net-20081216075629-zhgjzxgoh32453tu
parent: mbp at sourcefrog.net-20081216071030-dbxgukznexs9zqn8
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 18:56:29 +1100
message:
Choose the UIFactory class depending on the terminal capabilities
modified:
bzrlib/commands.py bzr.py-20050309040720-d10f4714595cf8c3
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.8.10
revision-id: mbp at sourcefrog.net-20081216071030-dbxgukznexs9zqn8
parent: mbp at sourcefrog.net-20081216070053-443injzwkblc0rij
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 18:10:30 +1100
message:
Fix up test_ui for new progress bars
modified:
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
------------------------------------------------------------
revno: 3882.8.9
revision-id: mbp at sourcefrog.net-20081216070053-443injzwkblc0rij
parent: mbp at sourcefrog.net-20081216065958-b4ce9x9w34xwan5a
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 18:00:53 +1100
message:
Move TextProgressView to ui.text
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.8.8
revision-id: mbp at sourcefrog.net-20081216065958-b4ce9x9w34xwan5a
parent: mbp at sourcefrog.net-20081216061801-7ty3ke724hruq0nw
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 17:59:58 +1100
message:
Progress and UI test cleanups
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.8.7
revision-id: mbp at sourcefrog.net-20081216061801-7ty3ke724hruq0nw
parent: mbp at sourcefrog.net-20081216061654-6hvc6dlf8srcpoxz
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 17:18:01 +1100
message:
Remove MissingProgressBarFinish exception
modified:
bzrlib/errors.py errors.py-20050309040759-20512168c4e14fbd
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
------------------------------------------------------------
revno: 3882.8.6
revision-id: mbp at sourcefrog.net-20081216061654-6hvc6dlf8srcpoxz
parent: mbp at sourcefrog.net-20081216061014-8hsdpmhake0s9ak6
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 17:16:54 +1100
message:
TextUIFactory ignores and deprecates the bar_type parameter
modified:
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.8.5
revision-id: mbp at sourcefrog.net-20081216061014-8hsdpmhake0s9ak6
parent: mbp at sourcefrog.net-20081216055124-uxx9245lbuef07le
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 17:10:14 +1100
message:
Progress tasks can indicate what kind of display is useful
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
------------------------------------------------------------
revno: 3882.8.4
revision-id: mbp at sourcefrog.net-20081216055124-uxx9245lbuef07le
parent: mbp at sourcefrog.net-20081216042643-lelt3haqjmedugq6
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 16:51:24 +1100
message:
All UI factories should support note()
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/tests/test_ui.py test_ui.py-20051130162854-458e667a7414af09
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.8.3
revision-id: mbp at sourcefrog.net-20081216042643-lelt3haqjmedugq6
parent: mbp at sourcefrog.net-20081216033052-crrxy0eo3njhtidl
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 15:26:43 +1100
message:
Move display of transport throughput into TextProgressView
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.8.2
revision-id: mbp at sourcefrog.net-20081216033052-crrxy0eo3njhtidl
parent: mbp at sourcefrog.net-20081216032241-6xuetbwb8xlifayh
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 14:30:52 +1100
message:
ProgressTask holds a reference to the ui that displays it
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
------------------------------------------------------------
revno: 3882.8.1
revision-id: mbp at sourcefrog.net-20081216032241-6xuetbwb8xlifayh
parent: mbp at sourcefrog.net-20081215085130-rqxig49n8g9jh8qt
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Tue 2008-12-16 14:22:41 +1100
message:
Remove experimental transport display from TTYProgressBar
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
------------------------------------------------------------
revno: 3882.7.10
revision-id: mbp at sourcefrog.net-20081224070433-6trk2e9btcx45o6s
parent: mbp at sourcefrog.net-20081224070318-pq87j6nbk3aocy6y
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Wed 2008-12-24 18:04:33 +1100
message:
CLIUIFactory implements (as stubs) progress methods
modified:
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
------------------------------------------------------------
revno: 3882.7.9
revision-id: mbp at sourcefrog.net-20081224070318-pq87j6nbk3aocy6y
parent: mbp at sourcefrog.net-20081215085130-rqxig49n8g9jh8qt
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Wed 2008-12-24 18:03:18 +1100
message:
Move the point at which sftp issues transport activity (thanks vila)
modified:
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
------------------------------------------------------------
revno: 3882.7.8
revision-id: mbp at sourcefrog.net-20081215085130-rqxig49n8g9jh8qt
parent: mbp at sourcefrog.net-20081215082857-asjzld70e2s1i0ta
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 19:51:30 +1100
message:
Progress layout tweaks
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.7.7
revision-id: mbp at sourcefrog.net-20081215082857-asjzld70e2s1i0ta
parent: mbp at sourcefrog.net-20081215063120-s06lzbt1fye3lbim
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 19:28:57 +1100
message:
Change progress bars to a more MVC style
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.7.6
revision-id: mbp at sourcefrog.net-20081215063120-s06lzbt1fye3lbim
parent: mbp at sourcefrog.net-20081215010123-diylgwx90yz0gfs3
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 17:31:20 +1100
message:
Preliminary support for drawing network io into the progress bar
modified:
bzrlib/progress.py progress.py-20050610070202-df9faaab791964c0
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.7.5
revision-id: mbp at sourcefrog.net-20081215010123-diylgwx90yz0gfs3
parent: mbp at sourcefrog.net-20081214200649-8ilmikjrp0r6utp1
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 12:01:23 +1100
message:
Further mockup of transport-based activity indicator.
The activity is now drawn by the UI layer, and it shows total traffic plus
approximate current rate.
This currently disables the regular progress bars.
modified:
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
bzrlib/ui/__init__.py ui.py-20050824083933-8cf663c763ba53a9
bzrlib/ui/text.py text.py-20051130153916-2e438cffc8afc478
------------------------------------------------------------
revno: 3882.7.4
revision-id: mbp at sourcefrog.net-20081214200649-8ilmikjrp0r6utp1
parent: mbp at sourcefrog.net-20081214200631-2elwxl7o6sbcpo0x
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 07:06:49 +1100
message:
SFTPTransport also sends activity from get()
modified:
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
------------------------------------------------------------
revno: 3882.7.3
revision-id: mbp at sourcefrog.net-20081214200631-2elwxl7o6sbcpo0x
parent: mbp at sourcefrog.net-20081214183716-rdtk0w8yvxubdd3k
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 07:06:31 +1100
message:
transport.get should specifically close the file handle
modified:
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
------------------------------------------------------------
revno: 3882.7.2
revision-id: mbp at sourcefrog.net-20081214183716-rdtk0w8yvxubdd3k
parent: mbp at sourcefrog.net-20081214183654-v91j52svczc56q9c
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 05:37:16 +1100
message:
Start reporting activity from sftp read access
modified:
bzrlib/transport/sftp.py sftp.py-20051019050329-ab48ce71b7e32dfe
------------------------------------------------------------
revno: 3882.7.1
revision-id: mbp at sourcefrog.net-20081214183654-v91j52svczc56q9c
parent: pqm at pqm.ubuntu.com-20081205181554-ofrdnafloc43bxkh
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: progress
timestamp: Mon 2008-12-15 05:36:54 +1100
message:
Add stub _report_activity method as a transport callback
modified:
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
=== modified file 'NEWS'
--- a/NEWS 2009-01-15 05:18:22 +0000
+++ b/NEWS 2009-01-15 07:34:16 +0000
@@ -4,6 +4,13 @@
.. contents::
+IN DEVELOPMENT
+--------------
+
+ IMPROVEMENTS:
+
+ * Progress bars now show the rate of activity for some sftp
+ operations, and they are drawn different. (Martin Pool, #172741)
NOT RELEASED YET
----------------
@@ -271,6 +278,10 @@
advantage of pycurl is that it checks ssl certificates.)
(John Arbash Meinel)
+ * The progress and UI classes have changed; the main APIs remain the
+ same but code that provides a new UI or progress bar class may
+ need to be updated. (Martin Pool)
+
* ``VersionedFiles.get_record_stream()`` can now return objects with a
storage_kind of ``chunked``. This is a collection (list/tuple) of
strings. You can use ``osutils.chunks_to_lines()`` to turn them into
=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py 2008-10-21 20:43:05 +0000
+++ b/bzrlib/commands.py 2008-12-16 07:56:29 +0000
@@ -868,8 +868,8 @@
def main(argv):
import bzrlib.ui
- from bzrlib.ui.text import TextUIFactory
- bzrlib.ui.ui_factory = TextUIFactory()
+ bzrlib.ui.ui_factory = bzrlib.ui.make_ui_for_terminal(
+ sys.stdin, sys.stdout, sys.stderr)
# Is this a final release version? If so, we should suppress warnings
if bzrlib.version_info[3] == 'final':
=== modified file 'bzrlib/errors.py'
--- a/bzrlib/errors.py 2009-01-08 16:57:10 +0000
+++ b/bzrlib/errors.py 2009-01-13 05:16:26 +0000
@@ -2171,11 +2171,6 @@
_fmt = "Cannot perform local-only commits on unbound branches."
-class MissingProgressBarFinish(BzrError):
-
- _fmt = "A nested progress bar was not 'finished' correctly."
-
-
class InvalidProgressBarType(BzrError):
_fmt = ("Environment variable BZR_PROGRESS_BAR='%(bar_type)s"
=== modified file 'bzrlib/progress.py'
--- a/bzrlib/progress.py 2008-04-24 07:22:53 +0000
+++ b/bzrlib/progress.py 2008-12-17 08:18:14 +0000
@@ -1,5 +1,4 @@
-# Copyright (C) 2005 Aaron Bentley <aaron.bentley at utoronto.ca>
-# Copyright (C) 2005, 2006 Canonical Ltd
+# Copyright (C) 2005, 2006, 2008 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -28,20 +27,19 @@
bzrlib it really is best to use bzrlib.ui.ui_factory.
"""
-# TODO: Optionally show elapsed time instead/as well as ETA; nicer
-# when the rate is unpredictable
import sys
import time
import os
-
-from bzrlib.lazy_import import lazy_import
-lazy_import(globals(), """
+import warnings
+
+
from bzrlib import (
errors,
+ osutils,
+ trace,
+ ui,
)
-""")
-
from bzrlib.trace import mutter
@@ -62,7 +60,69 @@
return True
-_progress_bar_types = {}
+class ProgressTask(object):
+ """Model component of a progress indicator.
+
+ Most code that needs to indicate progress should update one of these,
+ and it will in turn update the display, if one is present.
+
+ Code updating the task may also set fields as hints about how to display
+ it: show_pct, show_spinner, show_eta, show_count, show_bar. UIs
+ will not necessarily respect all these fields.
+ """
+
+ def __init__(self, parent_task=None, ui_factory=None):
+ self._parent_task = parent_task
+ self._last_update = 0
+ self.total_cnt = None
+ self.current_cnt = None
+ self.msg = ''
+ self.ui_factory = ui_factory
+ self.show_pct = False
+ self.show_spinner = True
+ self.show_eta = False,
+ self.show_count = True
+ self.show_bar = True
+
+ def update(self, msg, current_cnt=None, total_cnt=None):
+ self.msg = msg
+ self.current_cnt = current_cnt
+ if total_cnt:
+ self.total_cnt = total_cnt
+ self.ui_factory.show_progress(self)
+
+ def tick(self):
+ self.update(self.msg)
+
+ def finished(self):
+ self.ui_factory.progress_finished(self)
+
+ def make_sub_task(self):
+ return ProgressTask(self, self.ui_factory)
+
+ def _overall_completion_fraction(self, child_fraction=0.0):
+ """Return fractional completion of this task and its parents
+
+ Returns None if no completion can be computed."""
+ if self.total_cnt:
+ own_fraction = (float(self.current_cnt) + child_fraction) / self.total_cnt
+ else:
+ own_fraction = None
+ if self._parent_task is None:
+ return own_fraction
+ else:
+ if own_fraction is None:
+ own_fraction = 0.0
+ return self._parent_task._overall_completion_fraction(own_fraction)
+
+ def note(self, fmt_string, *args):
+ """Record a note without disrupting the progress bar."""
+ # XXX: shouldn't be here; put it in mutter or the ui instead
+ self.ui_factory.note(fmt_string % args)
+
+ def clear(self):
+ # XXX: shouldn't be here; put it in mutter or the ui instead
+ self.ui_factory.clear_term()
def ProgressBar(to_file=None, **kwargs):
@@ -87,7 +147,7 @@
_progress_bar_types.keys())
return _progress_bar_types[requested_bar_type](to_file=to_file, **kwargs)
-
+
class ProgressBarStack(object):
"""A stack of progress bars."""
@@ -147,8 +207,9 @@
def return_pb(self, bar):
"""Return bar after its been used."""
if bar is not self._stack[-1]:
- raise errors.MissingProgressBarFinish()
- self._stack.pop()
+ warnings.warn("%r is not currently active" % (bar,))
+ else:
+ self._stack.pop()
class _BaseProgressBar(object):
@@ -206,6 +267,7 @@
This can be used as the default argument for methods that
take an optional progress indicator."""
+
def tick(self):
pass
@@ -225,10 +287,6 @@
return DummyProgress(**kwargs)
-_progress_bar_types['dummy'] = DummyProgress
-_progress_bar_types['none'] = DummyProgress
-
-
class DotsProgressBar(_BaseProgressBar):
def __init__(self, **kwargs):
@@ -257,7 +315,6 @@
self.tick()
-_progress_bar_types['dots'] = DotsProgressBar
class TTYProgressBar(_BaseProgressBar):
@@ -329,8 +386,9 @@
self.tick()
def update(self, msg, current_cnt=None, total_cnt=None,
- child_fraction=0):
- """Update and redraw progress bar."""
+ child_fraction=0):
+ """Update and redraw progress bar.
+ """
if msg is None:
msg = self.last_msg
@@ -356,6 +414,9 @@
## self.child_fraction == child_fraction):
## return
+ if msg is None:
+ msg = ''
+
old_msg = self.last_msg
# save these for the tick() function
self.last_msg = msg
@@ -401,7 +462,7 @@
# make both fields the same size
t = '%i' % (self.last_total)
c = '%*i' % (len(t), self.last_cnt)
- count_str = ' ' + c + '/' + t
+ count_str = ' ' + c + '/' + t
if self.show_bar:
# progress bar, if present, soaks up all remaining space
@@ -425,7 +486,8 @@
else:
bar_str = ''
- m = spin_str + bar_str + self.last_msg + count_str + pct_str + eta_str
+ m = spin_str + bar_str + self.last_msg + count_str \
+ + pct_str + eta_str
self.to_file.write('\r%-*.*s' % (self.width - 1, self.width - 1, m))
self._have_output = True
#self.to_file.flush()
@@ -437,7 +499,6 @@
#self.to_file.flush()
-_progress_bar_types['tty'] = TTYProgressBar
class ChildProgress(_BaseProgressBar):
@@ -557,3 +618,10 @@
else:
self.cur_phase += 1
self.pb.update(self.message, self.cur_phase, self.total)
+
+
+_progress_bar_types = {}
+_progress_bar_types['dummy'] = DummyProgress
+_progress_bar_types['none'] = DummyProgress
+_progress_bar_types['tty'] = TTYProgressBar
+_progress_bar_types['dots'] = DotsProgressBar
=== modified file 'bzrlib/tests/blackbox/test_upgrade.py'
--- a/bzrlib/tests/blackbox/test_upgrade.py 2008-03-14 21:31:15 +0000
+++ b/bzrlib/tests/blackbox/test_upgrade.py 2009-01-13 05:07:27 +0000
@@ -1,6 +1,4 @@
-# Copyright (C) 2006, 2007 Canonical Ltd
-# Authors: Robert Collins <robert.collins at canonical.com>
-# and others
+# Copyright (C) 2006, 2007, 2009 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
=== modified file 'bzrlib/tests/test_sftp_transport.py'
--- a/bzrlib/tests/test_sftp_transport.py 2008-12-09 14:04:01 +0000
+++ b/bzrlib/tests/test_sftp_transport.py 2009-01-15 05:12:49 +0000
@@ -474,12 +474,17 @@
yield self._data[start:start+length]
+def _null_report_activity(*a, **k):
+ pass
+
+
class Test_SFTPReadvHelper(tests.TestCase):
def checkGetRequests(self, expected_requests, offsets):
if not paramiko_loaded:
raise TestSkipped('you must have paramiko to run this test')
- helper = _mod_sftp._SFTPReadvHelper(offsets, 'artificial_test')
+ helper = _mod_sftp._SFTPReadvHelper(offsets, 'artificial_test',
+ _null_report_activity)
self.assertEqual(expected_requests, helper._get_requests())
def test__get_requests(self):
@@ -499,7 +504,8 @@
def checkRequestAndYield(self, expected, data, offsets):
if not paramiko_loaded:
raise TestSkipped('you must have paramiko to run this test')
- helper = _mod_sftp._SFTPReadvHelper(offsets, 'artificial_test')
+ helper = _mod_sftp._SFTPReadvHelper(offsets, 'artificial_test',
+ _null_report_activity)
data_f = ReadvFile(data)
result = list(helper.request_and_yield_offsets(data_f))
self.assertEqual(expected, result)
=== modified file 'bzrlib/tests/test_ui.py'
--- a/bzrlib/tests/test_ui.py 2007-04-13 16:16:54 +0000
+++ b/bzrlib/tests/test_ui.py 2009-01-15 06:44:09 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005 Canonical Ltd
+# Copyright (C) 2005, 2008 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -101,11 +101,11 @@
def test_progress_note(self):
stderr = StringIO()
stdout = StringIO()
- ui_factory = TextUIFactory(bar_type=TTYProgressBar)
+ ui_factory = TextUIFactory(stdin=StringIO(''),
+ stderr=stderr,
+ stdout=stdout)
pb = ui_factory.nested_progress_bar()
try:
- pb.to_messages_file = stdout
- ui_factory._progress_bar_stack.bottom().to_file = stderr
result = pb.note('t')
self.assertEqual(None, result)
self.assertEqual("t\n", stdout.getvalue())
@@ -122,13 +122,12 @@
# The PQM redirects the output to a file, so it
# defaults to creating a Dots progress bar. we
# need to force it to believe we are a TTY
- ui_factory = TextUIFactory(bar_type=TTYProgressBar)
+ ui_factory = TextUIFactory(
+ stdin=StringIO(''),
+ stdout=stdout, stderr=stderr)
pb = ui_factory.nested_progress_bar()
try:
- pb.to_messages_file = stdout
- ui_factory._progress_bar_stack.bottom().to_file = stderr
# Create a progress update that isn't throttled
- pb.start_time -= 10
pb.update('x', 1, 1)
result = pb.note('t')
self.assertEqual(None, result)
@@ -142,10 +141,12 @@
def test_progress_nested(self):
# test factory based nested and popping.
- ui = TextUIFactory()
+ ui = TextUIFactory(None, None, None)
pb1 = ui.nested_progress_bar()
pb2 = ui.nested_progress_bar()
- self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
+ # We no longer warn about finishing unnested progress bars.
+ warnings, _ = self.callCatchWarnings(pb1.finished)
+ self.assertEqual(len(warnings), 0)
pb2.finished()
pb1.finished()
@@ -160,28 +161,19 @@
self.assertFalse(getattr(stack, 'note', False))
pb1 = stack.get_nested()
pb2 = stack.get_nested()
- self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
+ warnings, _ = self.callCatchWarnings(pb1.finished)
+ self.assertEqual(len(warnings), 1)
pb2.finished()
pb1.finished()
# the text ui factory never actually removes the stack once its setup.
# we need to be able to nest again correctly from here.
pb1 = stack.get_nested()
pb2 = stack.get_nested()
- self.assertRaises(errors.MissingProgressBarFinish, pb1.finished)
+ warnings, _ = self.callCatchWarnings(pb1.finished)
+ self.assertEqual(len(warnings), 1)
pb2.finished()
pb1.finished()
- def test_text_factory_setting_progress_bar(self):
- # we should be able to choose the progress bar type used.
- factory = TextUIFactory(bar_type=DotsProgressBar)
- bar = factory.nested_progress_bar()
- bar.finished()
- self.assertIsInstance(bar, DotsProgressBar)
-
- def test_cli_stdin_is_default_stdin(self):
- factory = CLIUIFactory()
- self.assertEqual(sys.stdin, factory.stdin)
-
def assert_get_bool_acceptance_of_user_input(self, factory):
factory.stdin = StringIO("y\nyes with garbage\n"
"yes\nn\nnot an answer\n"
@@ -212,28 +204,27 @@
self.assertEqual('', factory.stdin.readline())
def test_text_ui_getbool(self):
- factory = TextUIFactory()
+ factory = TextUIFactory(None, None, None)
self.assert_get_bool_acceptance_of_user_input(factory)
def test_text_factory_prompts_and_clears(self):
# a get_boolean call should clear the pb before prompting
- factory = TextUIFactory(bar_type=DotsProgressBar)
- factory.stdout = _TTYStringIO()
- factory.stdin = StringIO("yada\ny\n")
- pb = self.apply_redirected(factory.stdin, factory.stdout,
- factory.stdout, factory.nested_progress_bar)
- pb.start_time = None
- self.apply_redirected(factory.stdin, factory.stdout,
- factory.stdout, pb.update, "foo", 0, 1)
+ out = _TTYStringIO()
+ factory = TextUIFactory(stdin=StringIO("yada\ny\n"), stdout=out, stderr=out)
+ pb = factory.nested_progress_bar()
+ pb.show_bar = False
+ pb.show_spinner = False
+ pb.show_count = False
+ pb.update("foo", 0, 1)
self.assertEqual(True,
self.apply_redirected(None, factory.stdout,
factory.stdout,
factory.get_boolean,
"what do you want"))
- output = factory.stdout.getvalue()
- self.assertEqual("foo: .\n"
- "what do you want? [y/n]: what do you want? [y/n]: ",
- factory.stdout.getvalue())
- # stdin should be empty
+ output = out.getvalue()
+ self.assertContainsRe(factory.stdout.getvalue(),
+ "foo *\r\r *\r*")
+ self.assertContainsRe(factory.stdout.getvalue(),
+ r"what do you want\? \[y/n\]: what do you want\? \[y/n\]: ")
+ # stdin should have been totally consumed
self.assertEqual('', factory.stdin.readline())
-
=== modified file 'bzrlib/transport/__init__.py'
--- a/bzrlib/transport/__init__.py 2008-12-12 13:09:26 +0000
+++ b/bzrlib/transport/__init__.py 2008-12-24 07:37:37 +0000
@@ -41,6 +41,7 @@
errors,
osutils,
symbol_versioning,
+ ui,
urlutils,
)
""")
@@ -382,6 +383,18 @@
except TypeError: # We can't tell how many, because relpaths is a generator
return None
+ def _report_activity(self, bytes, direction):
+ """Notify that this transport has activity.
+
+ Implementations should call this from all methods that actually do IO.
+ Be careful that it's not called twice, if one method is implemented on
+ top of another.
+
+ :param bytes: Number of bytes read or written.
+ :param direction: 'read' or 'write' or None.
+ """
+ ui.ui_factory.report_transport_activity(self, bytes, direction)
+
def _update_pb(self, pb, msg, count, total):
"""Update the progress bar based on the current count
and total available, total may be None if it was
@@ -568,7 +581,11 @@
:param relpath: The relative path to the file
"""
- return self.get(relpath).read()
+ f = self.get(relpath)
+ try:
+ return f.read()
+ finally:
+ f.close()
@deprecated_method(one_four)
def get_smart_client(self):
=== modified file 'bzrlib/transport/sftp.py'
--- a/bzrlib/transport/sftp.py 2008-11-07 05:39:09 +0000
+++ b/bzrlib/transport/sftp.py 2009-01-15 05:12:49 +0000
@@ -1,5 +1,4 @@
-# Copyright (C) 2005 Robey Pointer <robey at lag.net>
-# Copyright (C) 2005, 2006, 2007 Canonical Ltd
+# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -140,15 +139,18 @@
# See _get_requests for an explanation.
_max_request_size = 32768
- def __init__(self, original_offsets, relpath):
+ def __init__(self, original_offsets, relpath, _report_activity):
"""Create a new readv helper.
:param original_offsets: The original requests given by the caller of
readv()
:param relpath: The name of the file (if known)
+ :param _report_activity: A Transport._report_activity bound method,
+ to be called as data arrives.
"""
self.original_offsets = list(original_offsets)
self.relpath = relpath
+ self._report_activity = _report_activity
def _get_requests(self):
"""Break up the offsets into individual requests over sftp.
@@ -219,6 +221,7 @@
if len(data) != length:
raise errors.ShortReadvError(self.relpath,
start, length, len(data))
+ self._report_activity(length, 'read')
if last_end is None:
# This is the first request, just buffer it
buffered_data = [data]
@@ -405,8 +408,7 @@
return False
def get(self, relpath):
- """
- Get the file at the given relative path.
+ """Get the file at the given relative path.
:param relpath: The relative path to the file
"""
@@ -420,6 +422,16 @@
self._translate_io_exception(e, path, ': error retrieving',
failure_exc=errors.ReadError)
+ def get_bytes(self, relpath):
+ # reimplement this here so that we can report how many bytes came back
+ f = self.get(relpath)
+ try:
+ bytes = f.read()
+ self._report_activity(len(bytes), 'read')
+ return bytes
+ finally:
+ f.close()
+
def _readv(self, relpath, offsets):
"""See Transport.readv()"""
# We overload the default readv() because we want to use a file
@@ -454,7 +466,7 @@
does not support ranges > 64K, so it caps the request size, and
just reads until it gets all the stuff it wants
"""
- helper = _SFTPReadvHelper(offsets, relpath)
+ helper = _SFTPReadvHelper(offsets, relpath, self._report_activity)
return helper.request_and_yield_offsets(fp)
def put_file(self, relpath, f, mode=None):
=== modified file 'bzrlib/ui/__init__.py'
--- a/bzrlib/ui/__init__.py 2008-03-11 22:15:16 +0000
+++ b/bzrlib/ui/__init__.py 2009-01-13 05:07:27 +0000
@@ -26,7 +26,9 @@
displays no output.
"""
+import os
import sys
+import warnings
from bzrlib.lazy_import import lazy_import
lazy_import(globals(), """
@@ -49,8 +51,7 @@
"""
def __init__(self):
- super(UIFactory, self).__init__()
- self._progress_bar_stack = None
+ self._task_stack = []
def get_password(self, prompt='', **kwargs):
"""Prompt the user for a password.
@@ -73,7 +74,18 @@
When the bar has been finished with, it should be released by calling
bar.finished().
"""
- raise NotImplementedError(self.nested_progress_bar)
+ if self._task_stack:
+ t = progress.ProgressTask(self._task_stack[-1], self)
+ else:
+ t = progress.ProgressTask(None, self)
+ self._task_stack.append(t)
+ return t
+
+ def progress_finished(self, task):
+ if task != self._task_stack[-1]:
+ warnings.warn("%r is not currently active" % (task,))
+ else:
+ del self._task_stack[-1]
def clear_term(self):
"""Prepare the terminal for output.
@@ -104,13 +116,26 @@
current_format_name,
basedir)
+ def report_transport_activity(self, transport, byte_count, direction):
+ """Called by transports as they do IO.
+
+ This may update a progress bar, spinner, or similar display.
+ By default it does nothing.
+ """
+ pass
+
+
class CLIUIFactory(UIFactory):
- """Common behaviour for command line UI factories."""
+ """Common behaviour for command line UI factories.
+
+ This is suitable for dumb terminals that can't repaint existing text."""
- def __init__(self):
- super(CLIUIFactory, self).__init__()
- self.stdin = sys.stdin
+ def __init__(self, stdin=None, stdout=None, stderr=None):
+ UIFactory.__init__(self)
+ self.stdin = stdin or sys.stdin
+ self.stdout = stdout or sys.stdout
+ self.stderr = stderr or sys.stderr
def get_boolean(self, prompt):
self.clear_term()
@@ -148,6 +173,15 @@
def prompt(self, prompt):
"""Emit prompt on the CLI."""
+ def clear_term(self):
+ pass
+
+ def show_progress(self, task):
+ pass
+
+ def progress_finished(self, task):
+ pass
+
class SilentUIFactory(CLIUIFactory):
"""A UI Factory which never prints anything.
@@ -155,19 +189,14 @@
This is the default UI, if another one is never registered.
"""
+ def __init__(self):
+ CLIUIFactory.__init__(self)
+
def get_password(self, prompt='', **kwargs):
return None
- def nested_progress_bar(self):
- if self._progress_bar_stack is None:
- self._progress_bar_stack = progress.ProgressBarStack(
- klass=progress.DummyProgress)
- return self._progress_bar_stack.get_nested()
-
- def clear_term(self):
- pass
-
- def recommend_upgrade(self, *args):
+
+ def note(self, msg):
pass
@@ -180,3 +209,23 @@
ui_factory = SilentUIFactory()
"""IMPORTANT: never import this symbol directly. ONLY ever access it as
ui.ui_factory."""
+
+
+def make_ui_for_terminal(stdin, stdout, stderr):
+ """Construct and return a suitable UIFactory for a text mode program.
+
+ If stdout is a smart terminal, this gets a smart UIFactory with
+ progress indicators, etc. If it's a dumb terminal, just plain text output.
+ """
+ isatty = getattr(stdin, 'isatty', None)
+ if isatty is None:
+ cls = CLIUIFactory
+ elif not isatty():
+ cls = CLIUIFactory
+ elif os.environ.get('TERM') in (None, 'dumb', ''):
+ # e.g. emacs compile window
+ cls = CLIUIFactory
+ else:
+ from bzrlib.ui.text import TextUIFactory
+ cls = TextUIFactory
+ return cls(stdin=stdin, stdout=stdout, stderr=stderr)
=== modified file 'bzrlib/ui/text.py'
--- a/bzrlib/ui/text.py 2007-08-15 04:33:34 +0000
+++ b/bzrlib/ui/text.py 2008-12-16 07:56:29 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005 Canonical Ltd
+# Copyright (C) 2005, 2008 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
"""
import sys
+import time
from bzrlib.lazy_import import lazy_import
lazy_import(globals(), """
@@ -28,7 +29,9 @@
from bzrlib import (
progress,
osutils,
+ symbol_versioning,
)
+
""")
from bzrlib.ui import CLIUIFactory
@@ -39,47 +42,189 @@
def __init__(self,
bar_type=None,
+ stdin=None,
stdout=None,
stderr=None):
"""Create a TextUIFactory.
:param bar_type: The type of progress bar to create. It defaults to
letting the bzrlib.progress.ProgressBar factory auto
- select.
+ select. Deprecated.
"""
- super(TextUIFactory, self).__init__()
- self._bar_type = bar_type
- if stdout is None:
- self.stdout = sys.stdout
- else:
- self.stdout = stdout
- if stderr is None:
- self.stderr = sys.stderr
- else:
- self.stderr = stderr
+ super(TextUIFactory, self).__init__(stdin=stdin,
+ stdout=stdout, stderr=stderr)
+ if bar_type:
+ symbol_versioning.warn(symbol_versioning.deprecated_in((1, 11, 0))
+ % "bar_type parameter")
+ # paints progress, network activity, etc
+ self._progress_view = TextProgressView(self.stderr)
def prompt(self, prompt):
"""Emit prompt on the CLI."""
self.stdout.write(prompt)
- def nested_progress_bar(self):
- """Return a nested progress bar.
-
- The actual bar type returned depends on the progress module which
- may return a tty or dots bar depending on the terminal.
- """
- if self._progress_bar_stack is None:
- self._progress_bar_stack = progress.ProgressBarStack(
- klass=self._bar_type)
- return self._progress_bar_stack.get_nested()
-
def clear_term(self):
"""Prepare the terminal for output.
This will, clear any progress bars, and leave the cursor at the
leftmost position."""
- if self._progress_bar_stack is None:
+ # XXX: If this is preparing to write to stdout, but that's for example
+ # directed into a file rather than to the terminal, and the progress
+ # bar _is_ going to the terminal, we shouldn't need
+ # to clear it. We might need to separately check for the case of
+ self._progress_view.clear()
+
+ def note(self, msg):
+ """Write an already-formatted message, clearing the progress bar if necessary."""
+ self.clear_term()
+ self.stdout.write(msg + '\n')
+
+ def report_transport_activity(self, transport, byte_count, direction):
+ """Called by transports as they do IO.
+
+ This may update a progress bar, spinner, or similar display.
+ By default it does nothing.
+ """
+ self._progress_view.show_transport_activity(byte_count)
+
+ def show_progress(self, task):
+ """A task has been updated and wants to be displayed.
+ """
+ self._progress_view.show_progress(task)
+
+ def progress_finished(self, task):
+ CLIUIFactory.progress_finished(self, task)
+ if not self._task_stack:
+ # finished top-level task
+ self._progress_view.clear()
+
+
+class TextProgressView(object):
+ """Display of progress bar and other information on a tty.
+
+ This shows one line of text, including possibly a network indicator, spinner,
+ progress bar, message, etc.
+
+ One instance of this is created and held by the UI, and fed updates when a
+ task wants to be painted.
+
+ Transports feed data to this through the ui_factory object.
+ """
+
+ def __init__(self, term_file):
+ self._term_file = term_file
+ # true when there's output on the screen we may need to clear
+ self._have_output = False
+ # XXX: We could listen for SIGWINCH and update the terminal width...
+ self._width = osutils.terminal_width()
+ self._last_transport_msg = ''
+ self._spin_pos = 0
+ # time we last repainted the screen
+ self._last_repaint = 0
+ # time we last got information about transport activity
+ self._transport_update_time = 0
+ self._task_fraction = None
+ self._last_task = None
+ self._total_byte_count = 0
+ self._bytes_since_update = 0
+
+ def _show_line(self, s):
+ n = self._width - 1
+ self._term_file.write('\r%-*.*s\r' % (n, n, s))
+
+ def clear(self):
+ if self._have_output:
+ self._show_line('')
+ self._have_output = False
+
+ def _render_bar(self):
+ # return a string for the progress bar itself
+ if (self._last_task is not None) and self._last_task.show_bar:
+ spin_str = r'/-\|'[self._spin_pos % 4]
+ self._spin_pos += 1
+ f = self._task_fraction or 0
+ cols = 20
+ # number of markers highlighted in bar
+ markers = int(round(float(cols) * f)) - 1
+ bar_str = '[' + ('#' * markers + spin_str).ljust(cols) + '] '
+ return bar_str
+ elif (self._last_task is None) or self._last_task.show_spinner:
+ spin_str = r'/-\|'[self._spin_pos % 4]
+ self._spin_pos += 1
+ return spin_str + ' '
+ else:
+ return ''
+
+ def _format_task(self, task):
+ if not task.show_count:
+ s = ''
+ elif task.total_cnt is not None:
+ s = ' %d/%d' % (task.current_cnt, task.total_cnt)
+ elif task.current_cnt is not None:
+ s = ' %d' % (task.current_cnt)
+ else:
+ s = ''
+ self._task_fraction = task._overall_completion_fraction()
+ # compose all the parent messages
+ t = task
+ m = task.msg
+ while t._parent_task:
+ t = t._parent_task
+ if t.msg:
+ m = t.msg + ':' + m
+ return m + s
+
+ def _repaint(self):
+ bar_string = self._render_bar()
+ if self._last_task:
+ task_msg = self._format_task(self._last_task)
+ else:
+ task_msg = ''
+ trans = self._last_transport_msg
+ if trans and task_msg:
+ trans += ' | '
+ s = (bar_string
+ + trans
+ + task_msg
+ )
+ self._show_line(s)
+ self._have_output = True
+
+ def show_progress(self, task):
+ self._last_task = task
+ now = time.time()
+ if now < self._last_repaint + 0.1:
return
- overall_pb = self._progress_bar_stack.bottom()
- if overall_pb is not None:
- overall_pb.clear()
+ if now > self._transport_update_time + 5:
+ # no recent activity; expire it
+ self._last_transport_msg = ''
+ self._last_repaint = now
+ self._repaint()
+
+ def show_transport_activity(self, byte_count):
+ """Called by transports as they do IO.
+
+ This may update a progress bar, spinner, or similar display.
+ By default it does nothing.
+ """
+ # XXX: Probably there should be a transport activity model, and that
+ # too should be seen by the progress view, rather than being poked in
+ # here.
+ self._total_byte_count += byte_count
+ self._bytes_since_update += byte_count
+ now = time.time()
+ if self._transport_update_time is None:
+ self._transport_update_time = now
+ elif now >= (self._transport_update_time + 0.2):
+ # guard against clock stepping backwards, and don't update too
+ # often
+ rate = self._bytes_since_update / (now - self._transport_update_time)
+ msg = ("%6dkB @ %4dkB/s" %
+ (self._total_byte_count>>10, int(rate)>>10,))
+ self._transport_update_time = now
+ self._last_repaint = now
+ self._bytes_since_update = 0
+ self._last_transport_msg = msg
+ self._repaint()
+
+
More information about the bazaar-commits
mailing list