Skip to content

Commit

Permalink
Merge pull request #3 from plaguss/cli
Browse files Browse the repository at this point in the history
v0.2.0
  • Loading branch information
plaguss committed Apr 7, 2023
2 parents fe8507e + 66c22fc commit acc005b
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 19 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Here should be the updates to the project. As they are completed they will be ad

- Add `pre-commit` to lint and format.


# 0.2.0

Added a small CLI to run the program from the console.

# 0.1.2

Fixed:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pytokei"
version = "0.1.2"
version = "0.2.0"
edition = "2021"
license = "MIT"
readme = "README.md"
Expand Down
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@ $ python
}
```

It includes a small CLI for simple use cases (run against the pytokei's folder):

```console
$ pytokei pytokei
pytokei
┏━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━┳━━━━━━━━━━┳━━━━━━━━┓
┃ language ┃ Files ┃ Lines ┃ Code ┃ Comments ┃ Blanks ┃
┡━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━╇━━━━━━━━━━╇━━━━━━━━┩
│ Rust │ 9 │ 1011 │ 846 │ 49 │ 116 │
│ Python │ 5 │ 568 │ 436 │ 13 │ 119 │
│ Markdown │ 11 │ 423 │ 123 │ 179 │ 121 │
│ Plain Text │ 4 │ 133 │ 0 │ 133 │ 0 │
│ TOML │ 3 │ 75 │ 59 │ 6 │ 10 │
│ YAML │ 1 │ 69 │ 63 │ 0 │ 6 │
│ Makefile │ 1 │ 26 │ 18 │ 0 │ 8 │
│ Dockerfile │ 1 │ 16 │ 7 │ 3 │ 6 │
│ Shell │ 3 │ 12 │ 12 │ 0 │ 0 │
│ Autoconf │ 3 │ 7 │ 7 │ 0 │ 0 │
└────────────┴───────┴───────┴──────┴──────────┴────────┘
```

For more information about `tokei`, please visit the original repo.

[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pytokei.svg)](https://pypi.org/project/pytokei/)
Expand Down
Binary file added docs/assets/pytokei-help.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/pytokei-itself.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/pytokei-no-color.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Command Line Interface

`pytokei` can be used from the console (at least for a subset of the options that [`tokei`](https://github.com/XAMPPRocky/tokei) offers).

The CLI is built using [`typer`](LINK) and [`rich`](LINK), so it should be self explanatory:

![pytokei-help](./assets/pytokei-help.png)

Only the compact report has been implemented:

![pytokei-itself](./assets/pytokei-itself.png)

With options to sort by the different variables, and ignore paths:

![pytokei-no-color](./assets/pytokei-no-color.png)

For the full detailed CLI you should use `tokei` directly.
6 changes: 6 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ Binaries are available for:

Otherwise, you can install from source which requires Rust stable to be installed.

To use the CLI, install with the needed dependencies (maybe with [`pipx`](https://github.com/pypa/pipx)).

```bash
pipx install pytokei[cli]
```

## Development

You will need:
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ plugins:
nav:
- Intro: index.md
- Usage: usage.md
- CLI: cli.md
- API:
- api/config.md
- api/language_type.md
Expand Down
11 changes: 10 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[build-system]
requires = ['maturin>=0.13,<0.14']
requires = ['maturin>=0.14,<0.15']
build-backend = 'maturin'

[project]
Expand All @@ -24,6 +24,15 @@ classifiers = [
]
description-file = "README.md"

[project.optional-dependencies]
cli = [
"typer>=0.7.0",
"rich>=13.3.0"
]

[project.scripts]
pytokei = "pytokei.cli:app"

[project.urls]
Homepage = 'https://github.com/plaguss/pytokei'
Documentation = 'https://plaguss.github.io/pytokei/'
Expand Down
19 changes: 7 additions & 12 deletions pytokei/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
from pytokei._pytokei import (
CodeStats,
Config,
Language,
Languages,
LanguageType,
Report,
Sort,
sort_types,
__version__
)
# fmt: off
from pytokei._pytokei import (CodeStats, Config, # type: ignore[attr-defined]
Language, Languages, LanguageType, Report, Sort,
__version__, sort_types)

# fmt: on

__all__ = [
"CodeStats",
Expand All @@ -19,5 +14,5 @@
"Report",
"Sort",
"sort_types",
"__version__"
"__version__",
]
138 changes: 138 additions & 0 deletions pytokei/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
from pathlib import Path
from typing import Dict, List, Tuple

import typer
from rich.console import Console
from rich.table import Table
from rich.text import Text

import pytokei

app = typer.Typer()

ReportType = Dict[str, Dict[str, int]]

REPORT_TO_POSITION = {
"files": 1,
"lines": 2,
"code": 3,
"comments": 4,
"blanks": 5,
}


def _report_as_list(report: ReportType) -> List[Tuple[str, int, int, int, int, int]]:
"""Transform the report to simplify sorting.
Args:
report (ReportType): Output from pytokei.
Returns:
List[List[str]]: report in a list of lists.
The first column corresponds to the languages,
then files, lines, code, comments and blanks.
"""
return [
(
lang,
result["files"],
result["lines"],
result["code"],
result["comments"],
result["blanks"],
)
for lang, result in report.items()
]


def to_table(
report: ReportType,
title: str = "pytokei report",
colored: bool = True,
sort: str = "lines",
) -> None:
"""Creates a rich table to print the report to the console.
Args:
report (Dict[str, Dict[str, int]]): pytokei's report.
title (str, optional): Title for the table. Defaults to "pytokei report".
colored (bool): Whether to report the table with colors or not.
sort (str, optional): Variable to sort the table. By default is not sorted.
"""
report_ = _report_as_list(report)

report_ = sorted(report_, key=lambda x: x[REPORT_TO_POSITION[sort]], reverse=True)

table = Table(title=title)
columns = ("language", "files", "lines", "code", "comments", "blanks")

if colored:
colors_even = (
"deep_sky_blue2",
"medium_purple",
"red",
"gold1",
"green3",
"grey82",
)
colors_odd = (
"deep_sky_blue3",
"dark_violet",
"dark_red",
"yellow",
"green4",
"grey39",
)
else:
colors_even = ("",) * 6
colors_odd = colors_even

table.add_column(
columns[0], justify="left", style=colors_even[0], header_style=colors_even[0]
)

for c, color in zip(columns[1:], colors_even[1:]):
table.add_column(
c.capitalize(), justify="right", style=color, header_style=color
)

for i, data in enumerate(report_):
colors = colors_even if (i % 2 == 0) else colors_odd
row = [Text(text=data[0], style=colors[0])]
for value, color in zip(data[1:], colors[1:]):
row.append(Text(text=str(value), style=color))

table.add_row(*row)

console = Console()
console.print(table)


@app.command()
def main(
path: Path = typer.Argument(..., help="Path to the file or directory to count."),
ignore_paths: str = typer.Option(
"nothing",
"--ignore-paths",
"-i",
help=(
"List of paths to ignore, comma separated. For example `/docs,pyproject.toml`"
),
),
sort: str = typer.Option(
"lines",
"-s",
"--sort",
help=f"If given, sorts the result by this value. Must be one of {set(REPORT_TO_POSITION.keys())}.",
),
colored: bool = typer.Option(
True, help="Whether to add color to the report or not."
),
) -> None: # pragma: no cover
"""Pytokei Command Line Interface."""
langs = pytokei.Languages()
conf = pytokei.Config() # Just use the default for now
langs.get_statistics([str(path)], ignore_paths.split(","), conf)
report = langs.report_compact_plain()

to_table(report, title=str(path), colored=colored, sort=sort)
6 changes: 3 additions & 3 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
#
attrs==22.1.0
# via pytest
exceptiongroup==1.0.0
# via pytest
iniconfig==1.1.1
# via pytest
packaging==21.3
# via pytest
pluggy==1.0.0
# via pytest
py==1.11.0
# via pytest
pyparsing==3.0.9
# via packaging
pytest==7.1.3
pytest==7.2.0
# via -r requirements/test.in
tomli==2.0.1
# via pytest
4 changes: 3 additions & 1 deletion tests/test_pytokei.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,6 @@ def test_languages_default_report_plain(self, languages):
stats = ["files", "lines", "code", "comments", "blanks"]
values_dockerfile = [1, 16, 7, 3, 6]
assert all([name in report.keys() for name in lang_names])
assert all([report["Dockerfile"][k] == v for k, v in zip(stats, values_dockerfile)])
assert all(
[report["Dockerfile"][k] == v for k, v in zip(stats, values_dockerfile)]
)

0 comments on commit acc005b

Please sign in to comment.