Esempio n. 1
0
def test_clean_all_cleans_all_maps(mapped_doubler):
    mapped_doubler.map(range(1), tag='yes-me')
    mapped_doubler.map(range(1))

    htmap.clean(all=True)

    assert len(htmap.get_tags()) == 0
Esempio n. 2
0
def test_old_tag_not_in_tags(mapped_doubler):
    m = mapped_doubler.map(range(2), tag="old")
    m.wait(timeout=180)

    m.retag("new")

    assert "old" not in htmap.get_tags()
Esempio n. 3
0
def test_old_tag_not_in_tags(mapped_doubler):
    m = mapped_doubler.map(range(2), tag='old')
    m.wait(timeout=180)

    m.retag('new')

    assert 'old' not in htmap.get_tags()
Esempio n. 4
0
def test_clean_only_removes_transient_maps(mapped_doubler):
    mapped_doubler.map(range(1), tag='not-me')
    mapped_doubler.map(range(1))

    htmap.clean()

    assert htmap.get_tags() == ('not-me', )
Esempio n. 5
0
def test_clean_removes_all_transient_maps(mapped_doubler):
    mapped_doubler.map(range(1))
    mapped_doubler.map(range(1))
    mapped_doubler.map(range(1))

    htmap.clean()

    assert len(htmap.get_tags()) == 0
Esempio n. 6
0
def _get_tags(all: bool, pattern: List[str], tags: List[str]) -> Tuple[str, ...]:
    if all:
        tags = list(htmap.get_tags())
    elif len(pattern) > 0:
        tags += _get_tags_from_patterns(pattern)

    _check_tags(tags)

    return tuple(tags)
Esempio n. 7
0
def vacate(tags, all):
    """Force maps to give up their claimed resources."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    for tag in tags:
        with make_spinner(f'Vacating map {tag} ...') as spinner:
            _cli_load(tag).vacate()
            spinner.succeed(f'Vacated map {tag}')
Esempio n. 8
0
def resume(tags, all):
    """Resume maps."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    for tag in tags:
        with make_spinner(f'Resuming map {tag} ...') as spinner:
            _cli_load(tag).resume()
            spinner.succeed(f'Resumed map {tag}')
Esempio n. 9
0
def pause(tags, all):
    """Pause maps."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    for tag in tags:
        with make_spinner(f'Pausing map {tag} ...') as spinner:
            _cli_load(tag).pause()
            spinner.succeed(f'Paused map {tag}')
Esempio n. 10
0
def hold(tags, all):
    """Hold maps."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    for tag in tags:
        with make_spinner(f'Holding map {tag} ...') as spinner:
            _cli_load(tag).hold()
            spinner.succeed(f'Held map {tag}')
Esempio n. 11
0
def remove(tags, all, force):
    """Remove maps."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    for tag in tags:
        with make_spinner(f'Removing map {tag} ...') as spinner:
            _cli_load(tag).remove(force=force)

            spinner.succeed(f'Removed map {tag}')
Esempio n. 12
0
def wait(tags, pattern, all):
    """Wait for maps to complete."""
    if all:
        tags = htmap.get_tags()
    elif len(pattern) > 0:
        tags += _get_tags_from_patterns(pattern)

    _check_tags(tags)

    if len(tags) == 0:
        return

    maps = sorted((_cli_load(tag) for tag in tags),
                  key=lambda m: (m.is_transient, m.tag))
    with make_spinner(text='Reading map component statuses...'):
        read_events(maps)

    try:
        longest_tag_len = max(len(tag) for tag in tags)
        bar_width = min(shutil.get_terminal_size().columns,
                        TOTAL_WIDTH - (longest_tag_len + 1))

        click.echo('\n' * (len(maps) - 1))
        while any(not map.is_done for map in maps):
            bars = []
            for map in maps:
                sc = collections.Counter(map.component_statuses)

                bar_lens = {
                    status:
                    _calculate_bar_component_len(sc[status], len(map),
                                                 bar_width)
                    for status, _ in STATUS_AND_COLOR
                }
                bar_lens[htmap.ComponentStatus.IDLE] += bar_width - sum(
                    bar_lens.values())

                bar = ''.join([
                    click.style('█' * bar_lens[status], fg=color)
                    for status, color in STATUS_AND_COLOR
                ])

                bars.append(f'{map.tag.ljust(longest_tag_len)} {bar}')

            msg = '\n'.join(bars)
            move = f'\033[{len(maps)}A\r'

            sys.stdout.write(move)
            click.echo(msg)

            time.sleep(1)
    except KeyboardInterrupt:  # bypass click's interrupt handling and let it exit quietly
        return
Esempio n. 13
0
def map(tags, all):
    """Rerun all of the components of any number of maps."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    for tag in tags:
        m = _cli_load(tag)
        with make_spinner(f'Rerunning map {tag} ...') as spinner:
            m.rerun()
            spinner.succeed(f'Reran map {tag}')
Esempio n. 14
0
def hold(tags, pattern, all):
    """Hold maps."""
    if all:
        tags = htmap.get_tags()
    elif len(pattern) > 0:
        tags += _get_tags_from_patterns(pattern)

    _check_tags(tags)

    for tag in tags:
        with make_spinner(f'Holding map {tag} ...') as spinner:
            _cli_load(tag).hold()
            spinner.succeed(f'Held map {tag}')
Esempio n. 15
0
def resume(tags, pattern, all):
    """Resume maps."""
    if all:
        tags = htmap.get_tags()
    elif len(pattern) > 0:
        tags += _get_tags_from_patterns(pattern)

    _check_tags(tags)

    for tag in tags:
        with make_spinner(f'Resuming map {tag} ...') as spinner:
            _cli_load(tag).resume()
            spinner.succeed(f'Resumed map {tag}')
Esempio n. 16
0
def errors(tags, all, limit):
    """Look at detailed error reports for a map."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    count = 0
    for tag in tags:
        m = _cli_load(tag)

        for report in m.error_reports():
            click.echo(report)
            count += 1
            if 0 < limit <= count:
                return
Esempio n. 17
0
def errors(tags, pattern, all, limit):
    """Look at detailed error reports for a map."""
    if all:
        tags = htmap.get_tags()
    elif len(pattern) > 0:
        tags += _get_tags_from_patterns(pattern)

    _check_tags(tags)

    count = 0
    for tag in tags:
        m = _cli_load(tag)

        for report in m.error_reports():
            click.echo(report)
            count += 1
            if 0 < limit <= count:
                return
Esempio n. 18
0
def reasons(tags, all):
    """Print the hold reasons for maps."""
    if all:
        tags = htmap.get_tags()

    _check_tags(tags)

    reps = []
    for tag in tags:
        m = _cli_load(tag)

        if len(m.holds) == 0:
            continue
        name = click.style(
            f'Map {m.tag} ({len(m.holds)} hold{"s" if len(m.holds) > 1 else ""})',
            bold=True,
        )
        reps.append(f'{name}\n{m.hold_report()}')

    click.echo('\n'.join(reps))
Esempio n. 19
0
def _get_tags_from_patterns(patterns):
    return tuple(set(sum((htmap.get_tags(p) for p in patterns), ())))
Esempio n. 20
0
def test_tags(mapped_doubler):
    mapped_doubler.map(range(1), tag='a')
    mapped_doubler.map(range(1), tag='b')
    mapped_doubler.map(range(1), tag='c')

    assert set(htmap.get_tags()) == {'a', 'b', 'c'}
Esempio n. 21
0
def status(no_state, no_meta, format, live, no_color):
    """
    Print the status of all maps.
    Transient maps are prefixed with a *
    """
    if format != 'text' and live:
        click.echo('ERROR: cannot produce non-text live data.', err=True)
        sys.exit(1)

    maps = sorted((_cli_load(tag) for tag in htmap.get_tags()),
                  key=lambda m: (m.is_transient, m.tag))
    if not no_state:
        with make_spinner(text='Reading map component statuses...'):
            read_events(maps)

    shared_kwargs = dict(
        include_state=not no_state,
        include_meta=not no_meta,
    )

    if format == 'json':
        msg = htmap.status_json(maps, **shared_kwargs)
    elif format == 'json_compact':
        msg = htmap.status_json(maps, **shared_kwargs, compact=True)
    elif format == 'csv':
        msg = htmap.status_csv(maps, **shared_kwargs)
    elif format == 'text':
        msg = _status(
            maps,
            **shared_kwargs,
            header_fmt=_HEADER_FMT if not no_color else None,
            row_fmt=_RowFmt(maps) if not no_color else None,
        )
    else:
        click.echo(f'ERROR: unknown format option "{format}"', err=True)
        sys.exit(1)

    click.echo(msg)

    try:
        while live:
            prev_len_lines = [len(line) for line in msg.splitlines()]

            maps = sorted(htmap.load_maps(),
                          key=lambda m: (m.is_transient, m.tag))
            msg = _status(
                maps,
                **shared_kwargs,
                header_fmt=_HEADER_FMT if not no_color else None,
                row_fmt=_RowFmt(maps) if not no_color else
                None,  # don't cache, must pass fresh each time
            )

            move = f'\033[{len(prev_len_lines)}A\r'
            clear = '\n'.join(' ' * l for l in prev_len_lines) + '\n'

            sys.stdout.write(move + clear + move)
            click.echo(msg)

            time.sleep(1)
    except KeyboardInterrupt:  # bypass click's interrupt handling and let it exit quietly
        return
Esempio n. 22
0
def _autocomplete_tag(ctx, args, incomplete):
    return sorted(tag for tag in htmap.get_tags()
                  if tag.startswith(incomplete) and tag not in args)
Esempio n. 23
0
def status(state, meta, format, live, color):
    """
    Print a status table for all of your maps.

    Transient maps are prefixed with a leading "*".
    """
    if format != "text" and live:
        click.echo("ERROR: cannot produce non-text live data.", err=True)
        sys.exit(1)

    maps = sorted(
        (_cli_load(tag) for tag in htmap.get_tags()),
        key=lambda m: (m.is_transient, m.tag),
    )
    for map in maps:
        if state:
            with make_spinner(
                    text=f"Reading component statuses for map {map.tag}..."):
                map.component_statuses
        if meta:
            with make_spinner(
                    text=f"Determining local data usage for map {map.tag}..."):
                map.local_data

    shared_kwargs = dict(
        include_state=state,
        include_meta=meta,
    )

    if format == "json":
        msg = htmap.status_json(maps, **shared_kwargs)
    elif format == "json_compact":
        msg = htmap.status_json(maps, **shared_kwargs, compact=True)
    elif format == "csv":
        msg = htmap.status_csv(maps, **shared_kwargs)
    elif format == "text":
        msg = _status(
            maps,
            **shared_kwargs,
            header_fmt=_HEADER_FMT if color else None,
            row_fmt=_RowFmt(maps) if color else None,
        )
    else:  # pragma: unreachable
        # this is a safeguard; this code is actually unreachable, because
        # click detects the invalid choice before we hit this
        click.echo(f'ERROR: unknown format option "{format}"', err=True)
        sys.exit(2)

    click.echo(msg)

    try:
        while live:
            prev_lines = list(msg.splitlines())
            prev_len_lines = [len(line) for line in prev_lines]

            maps = sorted(htmap.load_maps(),
                          key=lambda m: (m.is_transient, m.tag))
            msg = _status(
                maps,
                **shared_kwargs,
                header_fmt=_HEADER_FMT if color else None,
                row_fmt=_RowFmt(maps)
                if color else None,  # don't cache, must pass fresh each time
            )

            move = f"\033[{len(prev_len_lines)}A\r"
            clear = "\n".join(" " * len(click.unstyle(line))
                              for line in prev_lines) + "\n"

            sys.stdout.write(move + clear + move)
            click.echo(msg)

            time.sleep(1)
    except KeyboardInterrupt:  # bypass click's interrupt handling and let it exit quietly
        return
Esempio n. 24
0
def _fmt_tag_list(pattern: Optional[str] = None) -> str:
    return "\n".join(htmap.get_tags(pattern))
Esempio n. 25
0
def _get_tags_from_patterns(patterns: List[str]) -> List[str]:
    return list(set(sum((htmap.get_tags(p) for p in patterns), ())))
Esempio n. 26
0
def _autocomplete_tag(ctx, args, incomplete):
    return [tag for tag in htmap.get_tags() if incomplete in tag]
Esempio n. 27
0
def test_get_tag_with_pattern(mapped_doubler, tags, pattern, expected):
    for tag in tags:
        mapped_doubler.map(range(1), tag = tag)

    assert set(htmap.get_tags(pattern)) == set(expected)
Esempio n. 28
0
def test_get_tags(mapped_doubler):
    mapped_doubler.map(range(1), tag="a")
    mapped_doubler.map(range(1), tag="b")
    mapped_doubler.map(range(1), tag="c")

    assert set(htmap.get_tags()) == {"a", "b", "c"}
Esempio n. 29
0
def _tag_list() -> str:
    return '\n'.join(htmap.get_tags())