Skip to content

Commit 1bac9b5

Browse files
Merge pull request #959 from con-f-use/main
add 'info' command to cli
2 parents 45eb1b2 + 739a67c commit 1bac9b5

File tree

2 files changed

+100
-7
lines changed

2 files changed

+100
-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: 99 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
from __future__ import annotations
22

33
import argparse
4+
import json
45
import os
56
import sys
67

8+
from typing import Any
9+
710
from setuptools_scm import Configuration
811
from setuptools_scm._file_finders import find_files
912
from setuptools_scm._get_version_impl import _get_version
1013
from setuptools_scm.discover import walk_potential_roots
1114

1215

13-
def main(args: list[str] | None = None) -> None:
16+
def main(args: list[str] | None = None) -> int:
1417
opts = _get_cli_opts(args)
1518
inferred_root: str = opts.root or "."
1619

@@ -38,11 +41,8 @@ def main(args: list[str] | None = None) -> None:
3841
raise SystemExit("ERROR: no version found for", opts)
3942
if opts.strip_dev:
4043
version = version.partition(".dev")[0]
41-
print(version)
4244

43-
if opts.command == "ls":
44-
for fname in find_files(config.root):
45-
print(fname)
45+
return command(opts, version, config)
4646

4747

4848
def _get_cli_opts(args: list[str] | None) -> argparse.Namespace:
@@ -69,6 +69,30 @@ def _get_cli_opts(args: list[str] | None) -> argparse.Namespace:
6969
action="store_true",
7070
help="remove the dev/local parts of the version before printing the version",
7171
)
72+
parser.add_argument(
73+
"-N",
74+
"--no-version",
75+
action="store_true",
76+
help="do not include package version in the output",
77+
)
78+
output_formats = ["json", "plain", "key-value"]
79+
parser.add_argument(
80+
"-f",
81+
"--format",
82+
type=str.casefold,
83+
default="plain",
84+
help="specify output format",
85+
choices=output_formats,
86+
)
87+
parser.add_argument(
88+
"-q",
89+
"--query",
90+
type=str.casefold,
91+
nargs="*",
92+
help="display setuptools_scm settings according to query, "
93+
"e.g. dist_name, do not supply an argument in order to "
94+
"print a list of valid queries.",
95+
)
7296
parser.add_argument(
7397
"--force-write-version-files",
7498
action="store_true",
@@ -77,11 +101,80 @@ def _get_cli_opts(args: list[str] | None) -> argparse.Namespace:
77101
)
78102
sub = parser.add_subparsers(title="extra commands", dest="command", metavar="")
79103
# We avoid `metavar` to prevent printing repetitive information
80-
desc = "List files managed by the SCM"
104+
desc = "List information about the package, e.g. included files"
81105
sub.add_parser("ls", help=desc[0].lower() + desc[1:], description=desc)
82106
return parser.parse_args(args)
83107

84108

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

0 commit comments

Comments
 (0)