Skip to content

Commit 771046c

Browse files
committed
cli: extend ls comand for more info
1 parent 06e0aaf commit 771046c

File tree

2 files changed

+99
-7
lines changed

2 files changed

+99
-7
lines changed

src/setuptools_scm/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
from ._cli import main
44

55
if __name__ == "__main__":
6-
main()
6+
raise SystemExit(main())

src/setuptools_scm/_cli.py

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
from __future__ import annotations
22

33
import argparse
4+
import json
45
import os
56
import sys
7+
from typing import Any
68

79
from setuptools_scm import Configuration
810
from setuptools_scm._file_finders import find_files
911
from setuptools_scm._get_version_impl import _get_version
1012
from setuptools_scm.discover import walk_potential_roots
1113

1214

13-
def main(args: list[str] | None = None) -> None:
15+
def main(args: list[str] | None = None) -> int:
1416
opts = _get_cli_opts(args)
1517
inferred_root: str = opts.root or "."
1618

@@ -36,11 +38,8 @@ def main(args: list[str] | None = None) -> None:
3638
raise SystemExit("ERROR: no version found for", opts)
3739
if opts.strip_dev:
3840
version = version.partition(".dev")[0]
39-
print(version)
4041

41-
if opts.command == "ls":
42-
for fname in find_files(config.root):
43-
print(fname)
42+
return command(opts, version, config)
4443

4544

4645
def _get_cli_opts(args: list[str] | None) -> argparse.Namespace:
@@ -67,13 +66,106 @@ def _get_cli_opts(args: list[str] | None) -> argparse.Namespace:
6766
action="store_true",
6867
help="remove the dev/local parts of the version before printing the version",
6968
)
69+
parser.add_argument(
70+
"-N",
71+
"--no-version",
72+
action="store_true",
73+
help="do not include package version in the output",
74+
)
75+
output_formats = ["json", "plain", "key-value"]
76+
parser.add_argument(
77+
"-f",
78+
"--format",
79+
type=str.casefold,
80+
default="plain",
81+
help="specify output format",
82+
choices=output_formats,
83+
)
84+
parser.add_argument(
85+
"-q",
86+
"--query",
87+
type=str.casefold,
88+
nargs="*",
89+
help="display setuptools_scm settings according to query, "
90+
"e.g. dist_name, do not supply an argument in order to "
91+
"print a list of valid queries.",
92+
)
7093
sub = parser.add_subparsers(title="extra commands", dest="command", metavar="")
7194
# We avoid `metavar` to prevent printing repetitive information
72-
desc = "List files managed by the SCM"
95+
desc = "List information about the package, e.g. included files"
7396
sub.add_parser("ls", help=desc[0].lower() + desc[1:], description=desc)
7497
return parser.parse_args(args)
7598

7699

100+
# flake8: noqa: C901
101+
def command(opts: argparse.Namespace, version: str, config: Configuration) -> int:
102+
data: dict[str, Any] = {}
103+
104+
if opts.command == "ls":
105+
opts.query = ["files"]
106+
107+
if opts.query == []:
108+
opts.no_version = True
109+
sys.stderr.write("Available queries:\n\n")
110+
opts.query = ["queries"]
111+
data["queries"] = ["files"] + list(config.__dataclass_fields__.keys())
112+
113+
if opts.query is None:
114+
opts.query = []
115+
116+
if opts.no_version is False:
117+
data["version"] = version
118+
119+
if "files" in opts.query:
120+
data["files"] = find_files(config.root)
121+
122+
for q in opts.query:
123+
if q in ["files", "queries", "version"]:
124+
continue
125+
126+
try:
127+
if q.startswith("_"):
128+
raise AttributeError()
129+
data[q] = getattr(config, q)
130+
except AttributeError:
131+
sys.stderr.write(f"Error: unknown query: '{q}'\n")
132+
return 1
133+
134+
if opts.format == "json":
135+
print(json.dumps(data, indent=2))
136+
137+
if opts.format == "plain":
138+
_print_plain(data)
139+
140+
if opts.format == "key-value":
141+
_print_key_value(data)
142+
143+
return 0
144+
145+
146+
def _print_plain(data: dict[Any, Any]) -> None:
147+
version = data.pop("version", None)
148+
if version:
149+
print(version)
150+
files = data.pop("files", [])
151+
for file_ in files:
152+
print(file_)
153+
queries = data.pop("queries", [])
154+
for query in queries:
155+
print(query)
156+
if data:
157+
print("\n".join(data.values()))
158+
159+
160+
def _print_key_value(data: dict[Any, Any]) -> None:
161+
for key, value in data.items():
162+
if isinstance(value, str):
163+
print(f"{key} = {value}")
164+
else:
165+
str_value = "\n ".join(value)
166+
print(f"{key} = {str_value}")
167+
168+
77169
def _find_pyproject(parent: str) -> str:
78170
for directory in walk_potential_roots(os.path.abspath(parent)):
79171
pyproject = os.path.join(directory, "pyproject.toml")

0 commit comments

Comments
 (0)