Skip to content

Commit

Permalink
output for long waiting conan-list commands (#15354)
Browse files Browse the repository at this point in the history
* output for long waiting conan-list commands

* fixes
  • Loading branch information
memsharded authored Dec 27, 2023
1 parent bb7ee53 commit 8cc53ab
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
17 changes: 17 additions & 0 deletions conan/api/output.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fnmatch
import sys
import time

from colorama import Fore, Style

Expand Down Expand Up @@ -252,3 +253,19 @@ def cli_out_write(data, fg=None, bg=None, endline="\n", indentation=0):
data = f"{' ' * indentation}{data}{endline}"

sys.stdout.write(data)


class TimedOutput:
def __init__(self, interval, out=None, msg_format=None):
self._interval = interval
self._msg_format = msg_format
self._t = time.time()
self._out = out or ConanOutput()

def info(self, msg, *args, **kwargs):
t = time.time()
if t - self._t > self._interval:
self._t = t
if self._msg_format:
msg = self._msg_format(msg, *args, **kwargs)
self._out.info(msg)
12 changes: 11 additions & 1 deletion conan/api/subapi/list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Dict

from conan.api.model import PackagesList
from conan.api.output import ConanOutput
from conan.api.output import ConanOutput, TimedOutput
from conan.internal.conan_app import ConanApp
from conans.errors import ConanException, NotFoundException
from conans.model.info import load_binary_info
Expand Down Expand Up @@ -99,11 +99,14 @@ def select(self, pattern, package_query=None, remote=None, lru=None):
search_ref = pattern.search_ref
app = ConanApp(self.conan_api.cache_folder, self.conan_api.config.global_conf)
limit_time = timelimit(lru) if lru else None
out = ConanOutput()
remote_name = "local cache" if not remote else remote.name
if search_ref:
refs = self.conan_api.search.recipes(search_ref, remote=remote)
refs = pattern.filter_versions(refs)
refs = sorted(refs) # Order alphabetical and older versions first
pattern.check_refs(refs)
out.info(f"Found {len(refs)} pkg/version recipes matching {search_ref} in {remote_name}")
else:
refs = [RecipeReference(pattern.name, pattern.version, pattern.user, pattern.channel)]

Expand All @@ -112,7 +115,12 @@ def select(self, pattern, package_query=None, remote=None, lru=None):
select_bundle.add_refs(refs)
return select_bundle

def msg_format(msg, item, total):
return msg + f" ({total.index(item)}/{len(total)})"

trefs = TimedOutput(5, msg_format=msg_format)
for r in refs: # Older versions first
trefs.info(f"Listing revisions of {r} in {remote_name}", r, refs)
if pattern.is_latest_rrev or pattern.rrev is None:
rrev = self.latest_recipe_revision(r, remote)
if rrev is None:
Expand All @@ -131,7 +139,9 @@ def select(self, pattern, package_query=None, remote=None, lru=None):
if pattern.package_id is None: # Stop if not displaying binaries
continue

trrevs = TimedOutput(5, msg_format=msg_format)
for rrev in rrevs:
trrevs.info(f"Listing binaries of {rrev.repr_notime()} in {remote_name}", rrev, rrevs)
prefs = []
if "*" not in pattern.package_id and pattern.prev is not None:
prefs.append(PkgReference(rrev, package_id=pattern.package_id))
Expand Down
16 changes: 8 additions & 8 deletions conans/client/downloaders/file_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import time


from conan.api.output import ConanOutput
from conan.api.output import ConanOutput, TimedOutput
from conans.client.rest import response_to_str
from conans.errors import ConanException, NotFoundException, AuthenticationException, \
ForbiddenException, ConanConnectionError, RequestErrorException
Expand Down Expand Up @@ -104,8 +104,13 @@ def get_total_length():
try:
total_length = get_total_length()
is_large_file = total_length > 10000000 # 10 MB
t_start = time.time()
base_name = os.path.basename(file_path)

def msg_format(msg, downloaded):
perc = int(total_downloaded_size * 100 / total_length)
return msg + f" {human_size(downloaded)} {perc}% {base_name}"
timed_output = TimedOutput(10, out=self._output, msg_format=msg_format)

if is_large_file:
hs = human_size(total_length)
action = "Downloading" if range_start == 0 else "Continuing download of"
Expand All @@ -119,12 +124,7 @@ def get_total_length():
file_handler.write(chunk)
total_downloaded_size += len(chunk)
if is_large_file:
t = time.time()
if t - t_start > 10: # Every 10 seconds
hs = human_size(total_downloaded_size)
perc = int(total_downloaded_size*100/total_length)
self._output.info(f"Downloaded {hs} {perc}% {base_name}")
t_start = t
timed_output.info("Downloaded", total_downloaded_size)

gzip = (response.headers.get("content-encoding") == "gzip")
response.close()
Expand Down
4 changes: 2 additions & 2 deletions conans/test/integration/command_v2/list_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def check(client, pattern, remote, expected):
expected_output = f"{r_msg}\n" + expected
expected_output = re.sub(r"\(.*\)", "", expected_output)
output = re.sub(r"\(.*\)", "", str(client.out))
assert expected_output == output
assert expected_output in output

@staticmethod
def check_json(client, pattern, remote, expected):
Expand Down Expand Up @@ -293,7 +293,7 @@ def check(client, pattern, remote, expected):
expected_output = f"{r_msg}\n" + expected
expected_output = re.sub(r"\(.*\)", "", expected_output)
output = re.sub(r"\(.*\)", "", str(client.out))
assert expected_output == output
assert expected_output in output

@staticmethod
def check_json(client, pattern, remote, expected):
Expand Down
6 changes: 3 additions & 3 deletions conans/test/integration/command_v2/search_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def test_search_by_name(self):
" {}\n".format(recipe_name)
)

assert expected_output == self.client.out
assert expected_output in self.client.out

def test_search_in_all_remotes(self):
remote1 = "remote1"
Expand Down Expand Up @@ -144,7 +144,7 @@ def test_search_in_all_remotes(self):
self._add_recipe(remote2, remote2_recipe2)

self.client.run("search test_recipe")
assert expected_output == self.client.out
assert expected_output in self.client.out

def test_search_in_one_remote(self):
remote1 = "remote1"
Expand Down Expand Up @@ -201,7 +201,7 @@ def test_search_package_found_in_one_remote(self):
self._add_recipe(remote2, remote2_recipe2)

self.client.run("search test_recipe")
assert expected_output == self.client.out
assert expected_output in self.client.out

def test_search_in_missing_remote(self):
remote1 = "remote1"
Expand Down

0 comments on commit 8cc53ab

Please sign in to comment.