mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-06-01 15:39:47 +00:00
info: add --format and --include-summary/--include-projects options
Add --format={text,json} to produce machine-readable output, and
boolean options to control which sections are displayed:
--include-summary / --no-include-summary (default: on)
--include-projects / --no-include-projects (default: on)
The JSON output respects the include flags, so callers can request
only the fields they need (e.g. `repo info --format=json
--no-include-projects` for manifest metadata only).
Change-Id: I9641bc4023b630d9c61c5170eb86e5f3b787236f
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/569203
Commit-Queue: Carlos Fernandez <carlosfsanz@meta.com>
Reviewed-by: Mike Frysinger <vapier@google.com>
Reviewed-by: Gavin Mak <gavinmak@google.com>
Reviewed-by: Carlos Fernandez <carlosfsanz@meta.com>
Tested-by: Carlos Fernandez <carlosfsanz@meta.com>
This commit is contained in:
committed by
gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
e3eadd3728
commit
27d2232eb3
+17
-2
@@ -1,10 +1,10 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man.
|
.\" DO NOT MODIFY THIS FILE! It was generated by help2man.
|
||||||
.TH REPO "1" "July 2022" "repo info" "Repo Manual"
|
.TH REPO "1" "May 2026" "repo info" "Repo Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
repo \- repo info - manual page for repo info
|
repo \- repo info - manual page for repo info
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B repo
|
.B repo
|
||||||
\fI\,info \/\fR[\fI\,-dl\/\fR] [\fI\,-o \/\fR[\fI\,-c\/\fR]] [\fI\,<project>\/\fR...]
|
\fI\,info \/\fR[\fI\,-dl\/\fR] [\fI\,-o \/\fR[\fI\,-c\/\fR]] [\fI\,--format=<format>\/\fR] [\fI\,<project>\/\fR...]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Summary
|
Summary
|
||||||
.PP
|
.PP
|
||||||
@@ -21,6 +21,18 @@ branches
|
|||||||
\fB\-o\fR, \fB\-\-overview\fR
|
\fB\-o\fR, \fB\-\-overview\fR
|
||||||
show overview of all local commits
|
show overview of all local commits
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-\-include\-summary\fR
|
||||||
|
include manifest summary (default: true)
|
||||||
|
.TP
|
||||||
|
\fB\-\-no\-include\-summary\fR
|
||||||
|
exclude manifest summary
|
||||||
|
.TP
|
||||||
|
\fB\-\-include\-projects\fR
|
||||||
|
include project details (default: true)
|
||||||
|
.TP
|
||||||
|
\fB\-\-no\-include\-projects\fR
|
||||||
|
exclude project details
|
||||||
|
.TP
|
||||||
\fB\-c\fR, \fB\-\-current\-branch\fR
|
\fB\-c\fR, \fB\-\-current\-branch\fR
|
||||||
consider only checked out branches
|
consider only checked out branches
|
||||||
.TP
|
.TP
|
||||||
@@ -29,6 +41,9 @@ consider all local branches
|
|||||||
.TP
|
.TP
|
||||||
\fB\-l\fR, \fB\-\-local\-only\fR
|
\fB\-l\fR, \fB\-\-local\-only\fR
|
||||||
disable all remote operations
|
disable all remote operations
|
||||||
|
.TP
|
||||||
|
\fB\-\-format\fR=\fI\,FORMAT\/\fR
|
||||||
|
output format: text, json (default: text)
|
||||||
.SS Logging options:
|
.SS Logging options:
|
||||||
.TP
|
.TP
|
||||||
\fB\-v\fR, \fB\-\-verbose\fR
|
\fB\-v\fR, \fB\-\-verbose\fR
|
||||||
|
|||||||
+139
-27
@@ -12,7 +12,11 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import enum
|
||||||
|
import json
|
||||||
import optparse
|
import optparse
|
||||||
|
import sys
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
from color import Coloring
|
from color import Coloring
|
||||||
from command import PagedCommand
|
from command import PagedCommand
|
||||||
@@ -20,6 +24,16 @@ from git_refs import R_HEADS
|
|||||||
from git_refs import R_M
|
from git_refs import R_M
|
||||||
|
|
||||||
|
|
||||||
|
class OutputFormat(enum.Enum):
|
||||||
|
"""Type for the requested output format."""
|
||||||
|
|
||||||
|
# Human-readable text output.
|
||||||
|
TEXT = enum.auto()
|
||||||
|
|
||||||
|
# Machine-readable JSON output.
|
||||||
|
JSON = enum.auto()
|
||||||
|
|
||||||
|
|
||||||
class _Coloring(Coloring):
|
class _Coloring(Coloring):
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
Coloring.__init__(self, config, "status")
|
Coloring.__init__(self, config, "status")
|
||||||
@@ -30,7 +44,7 @@ class Info(PagedCommand):
|
|||||||
helpSummary = (
|
helpSummary = (
|
||||||
"Get info on the manifest branch, current branch or unmerged branches"
|
"Get info on the manifest branch, current branch or unmerged branches"
|
||||||
)
|
)
|
||||||
helpUsage = "%prog [-dl] [-o [-c]] [<project>...]"
|
helpUsage = "%prog [-dl] [-o [-c]] [--format=<format>] [<project>...]"
|
||||||
|
|
||||||
def _Options(self, p):
|
def _Options(self, p):
|
||||||
p.add_option(
|
p.add_option(
|
||||||
@@ -46,6 +60,30 @@ class Info(PagedCommand):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="show overview of all local commits",
|
help="show overview of all local commits",
|
||||||
)
|
)
|
||||||
|
p.add_option(
|
||||||
|
"--include-summary",
|
||||||
|
action="store_true",
|
||||||
|
default=True,
|
||||||
|
help="include manifest summary (default: true)",
|
||||||
|
)
|
||||||
|
p.add_option(
|
||||||
|
"--no-include-summary",
|
||||||
|
dest="include_summary",
|
||||||
|
action="store_false",
|
||||||
|
help="exclude manifest summary",
|
||||||
|
)
|
||||||
|
p.add_option(
|
||||||
|
"--include-projects",
|
||||||
|
action="store_true",
|
||||||
|
default=True,
|
||||||
|
help="include project details (default: true)",
|
||||||
|
)
|
||||||
|
p.add_option(
|
||||||
|
"--no-include-projects",
|
||||||
|
dest="include_projects",
|
||||||
|
action="store_false",
|
||||||
|
help="exclude project details",
|
||||||
|
)
|
||||||
p.add_option(
|
p.add_option(
|
||||||
"-c",
|
"-c",
|
||||||
"--current-branch",
|
"--current-branch",
|
||||||
@@ -72,8 +110,37 @@ class Info(PagedCommand):
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="disable all remote operations",
|
help="disable all remote operations",
|
||||||
)
|
)
|
||||||
|
formats = tuple(x.lower() for x in OutputFormat.__members__.keys())
|
||||||
|
p.add_option(
|
||||||
|
"--format",
|
||||||
|
default=OutputFormat.TEXT.name.lower(),
|
||||||
|
choices=formats,
|
||||||
|
help=f"output format: {', '.join(formats)} (default: %default)",
|
||||||
|
)
|
||||||
|
|
||||||
|
def WantPager(self, opt):
|
||||||
|
return OutputFormat[opt.format.upper()] == OutputFormat.TEXT
|
||||||
|
|
||||||
|
def ValidateOptions(self, opt, args):
|
||||||
|
output_format = OutputFormat[opt.format.upper()]
|
||||||
|
if output_format == OutputFormat.JSON:
|
||||||
|
if opt.all:
|
||||||
|
self.OptionParser.error("--diff is not supported with JSON")
|
||||||
|
if opt.overview:
|
||||||
|
self.OptionParser.error("--overview is not supported with JSON")
|
||||||
|
|
||||||
def Execute(self, opt, args):
|
def Execute(self, opt, args):
|
||||||
|
if not opt.this_manifest_only:
|
||||||
|
self.manifest = self.manifest.outer_client
|
||||||
|
|
||||||
|
output_format = OutputFormat[opt.format.upper()]
|
||||||
|
if output_format == OutputFormat.JSON:
|
||||||
|
self._ExecuteJson(opt, args)
|
||||||
|
else:
|
||||||
|
self._ExecuteText(opt, args)
|
||||||
|
|
||||||
|
def _ExecuteText(self, opt, args) -> None:
|
||||||
|
"""Output info as human-readable text."""
|
||||||
self.out = _Coloring(self.client.globalConfig)
|
self.out = _Coloring(self.client.globalConfig)
|
||||||
self.heading = self.out.printer("heading", attr="bold")
|
self.heading = self.out.printer("heading", attr="bold")
|
||||||
self.headtext = self.out.nofmt_printer("headtext", fg="yellow")
|
self.headtext = self.out.nofmt_printer("headtext", fg="yellow")
|
||||||
@@ -84,37 +151,82 @@ class Info(PagedCommand):
|
|||||||
|
|
||||||
self.opt = opt
|
self.opt = opt
|
||||||
|
|
||||||
if not opt.this_manifest_only:
|
if opt.include_summary:
|
||||||
self.manifest = self.manifest.outer_client
|
self._printSummary()
|
||||||
manifestConfig = self.manifest.manifestProject.config
|
|
||||||
mergeBranch = manifestConfig.GetBranch("default").merge
|
|
||||||
manifestGroups = self.manifest.GetManifestGroupsStr()
|
|
||||||
|
|
||||||
self.heading("Manifest branch: ")
|
if not opt.include_projects:
|
||||||
if self.manifest.default.revisionExpr:
|
return
|
||||||
self.headtext(self.manifest.default.revisionExpr)
|
elif not opt.overview:
|
||||||
self.out.nl()
|
|
||||||
self.heading("Manifest merge branch: ")
|
|
||||||
# The manifest might not have a merge branch if it isn't in a git repo,
|
|
||||||
# e.g. if `repo init --standalone-manifest` is used.
|
|
||||||
self.headtext(mergeBranch or "")
|
|
||||||
self.out.nl()
|
|
||||||
self.heading("Manifest groups: ")
|
|
||||||
self.headtext(manifestGroups)
|
|
||||||
self.out.nl()
|
|
||||||
sp = self.manifest.superproject
|
|
||||||
srev = sp.commit_id if sp and sp.commit_id else "None"
|
|
||||||
self.heading("Superproject revision: ")
|
|
||||||
self.headtext(srev)
|
|
||||||
self.out.nl()
|
|
||||||
|
|
||||||
self.printSeparator()
|
|
||||||
|
|
||||||
if not opt.overview:
|
|
||||||
self._printDiffInfo(opt, args)
|
self._printDiffInfo(opt, args)
|
||||||
else:
|
else:
|
||||||
self._printCommitOverview(opt, args)
|
self._printCommitOverview(opt, args)
|
||||||
|
|
||||||
|
def _getSummaryData(self) -> Dict[str, Any]:
|
||||||
|
"""Gather manifest summary data as a dict."""
|
||||||
|
manifestConfig = self.manifest.manifestProject.config
|
||||||
|
mergeBranch = manifestConfig.GetBranch("default").merge
|
||||||
|
manifestGroups = self.manifest.GetManifestGroupsStr()
|
||||||
|
sp = self.manifest.superproject
|
||||||
|
srev = sp.commit_id if sp and sp.commit_id else None
|
||||||
|
return {
|
||||||
|
"manifest_branch": self.manifest.default.revisionExpr or "",
|
||||||
|
"manifest_merge_branch": mergeBranch or "",
|
||||||
|
"manifest_groups": manifestGroups,
|
||||||
|
"superproject_revision": srev,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _getProjectData(self, project) -> Dict[str, Any]:
|
||||||
|
"""Gather project data as a dict."""
|
||||||
|
data = {
|
||||||
|
"name": project.name,
|
||||||
|
"mount_path": project.worktree,
|
||||||
|
"current_revision": project.GetRevisionId(),
|
||||||
|
"manifest_revision": project.revisionExpr,
|
||||||
|
"local_branches": list(project.GetBranches()),
|
||||||
|
}
|
||||||
|
currentBranch = project.CurrentBranch
|
||||||
|
if currentBranch:
|
||||||
|
data["current_branch"] = currentBranch
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _ExecuteJson(self, opt, args) -> None:
|
||||||
|
"""Output info as JSON."""
|
||||||
|
result = {}
|
||||||
|
if opt.include_summary:
|
||||||
|
result["summary"] = self._getSummaryData()
|
||||||
|
if opt.include_projects:
|
||||||
|
projs = self.GetProjects(
|
||||||
|
args, all_manifests=not opt.this_manifest_only
|
||||||
|
)
|
||||||
|
result["projects"] = [self._getProjectData(p) for p in projs]
|
||||||
|
|
||||||
|
json_settings = {
|
||||||
|
# JSON style guide says Unicode characters are fully allowed.
|
||||||
|
"ensure_ascii": False,
|
||||||
|
# We use 2 space indent to match JSON style guide.
|
||||||
|
"indent": 2,
|
||||||
|
"separators": (",", ": "),
|
||||||
|
"sort_keys": True,
|
||||||
|
}
|
||||||
|
sys.stdout.write(json.dumps(result, **json_settings) + "\n")
|
||||||
|
|
||||||
|
def _printSummary(self) -> None:
|
||||||
|
"""Print manifest summary in text format."""
|
||||||
|
data = self._getSummaryData()
|
||||||
|
self.heading("Manifest branch: ")
|
||||||
|
self.headtext(data["manifest_branch"])
|
||||||
|
self.out.nl()
|
||||||
|
self.heading("Manifest merge branch: ")
|
||||||
|
self.headtext(data["manifest_merge_branch"])
|
||||||
|
self.out.nl()
|
||||||
|
self.heading("Manifest groups: ")
|
||||||
|
self.headtext(data["manifest_groups"])
|
||||||
|
self.out.nl()
|
||||||
|
self.heading("Superproject revision: ")
|
||||||
|
self.headtext(data["superproject_revision"] or "None")
|
||||||
|
self.out.nl()
|
||||||
|
self.printSeparator()
|
||||||
|
|
||||||
def printSeparator(self):
|
def printSeparator(self):
|
||||||
self.text("----------------------------")
|
self.text("----------------------------")
|
||||||
self.out.nl()
|
self.out.nl()
|
||||||
|
|||||||
@@ -0,0 +1,201 @@
|
|||||||
|
# Copyright (C) 2026 The Android Open Source Project
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
"""Unittests for the subcmds/info.py module."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from subcmds import info
|
||||||
|
|
||||||
|
|
||||||
|
def _get_cmd() -> info.Info:
|
||||||
|
"""Build a mock-backed Info command for testing."""
|
||||||
|
manifest = mock.MagicMock()
|
||||||
|
manifest.default.revisionExpr = "refs/heads/main"
|
||||||
|
manifest.manifestProject.config.GetBranch.return_value.merge = (
|
||||||
|
"refs/heads/main"
|
||||||
|
)
|
||||||
|
manifest.GetManifestGroupsStr.return_value = "all"
|
||||||
|
manifest.superproject = None
|
||||||
|
manifest.outer_client = manifest
|
||||||
|
|
||||||
|
client = mock.MagicMock()
|
||||||
|
git_event_log = mock.MagicMock()
|
||||||
|
|
||||||
|
return info.Info(
|
||||||
|
manifest=manifest,
|
||||||
|
client=client,
|
||||||
|
git_event_log=git_event_log,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_include_options_default_true() -> None:
|
||||||
|
"""Both include options should default to True."""
|
||||||
|
opts, _ = _get_cmd().OptionParser.parse_args([])
|
||||||
|
assert opts.include_summary
|
||||||
|
assert opts.include_projects
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_include_summary_parses() -> None:
|
||||||
|
"""--no-include-summary should set include_summary to False."""
|
||||||
|
opts, _ = _get_cmd().OptionParser.parse_args(["--no-include-summary"])
|
||||||
|
assert not opts.include_summary
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_include_projects_parses() -> None:
|
||||||
|
"""--no-include-projects should set include_projects to False."""
|
||||||
|
opts, _ = _get_cmd().OptionParser.parse_args(["--no-include-projects"])
|
||||||
|
assert not opts.include_projects
|
||||||
|
|
||||||
|
|
||||||
|
def test_format_default_text() -> None:
|
||||||
|
"""Default format should be text."""
|
||||||
|
opts, _ = _get_cmd().OptionParser.parse_args([])
|
||||||
|
assert opts.format == "text"
|
||||||
|
|
||||||
|
|
||||||
|
def test_format_json_parses() -> None:
|
||||||
|
"""--format=json should be accepted."""
|
||||||
|
opts, _ = _get_cmd().OptionParser.parse_args(["--format=json"])
|
||||||
|
assert opts.format == "json"
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_include_projects_skips_projects() -> None:
|
||||||
|
"""--no-include-projects should skip project iteration."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(["--no-include-projects"])
|
||||||
|
|
||||||
|
with mock.patch.object(
|
||||||
|
cmd, "_printDiffInfo"
|
||||||
|
) as mock_diff, mock.patch.object(
|
||||||
|
cmd, "_printCommitOverview"
|
||||||
|
) as mock_overview:
|
||||||
|
cmd.Execute(opts, args)
|
||||||
|
mock_diff.assert_not_called()
|
||||||
|
mock_overview.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_include_summary_skips_summary() -> None:
|
||||||
|
"""--no-include-summary should not query or print manifest metadata."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(["--no-include-summary"])
|
||||||
|
|
||||||
|
with mock.patch.object(cmd, "_printDiffInfo"):
|
||||||
|
cmd.Execute(opts, args)
|
||||||
|
cmd.manifest.GetManifestGroupsStr.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_calls_diff_info() -> None:
|
||||||
|
"""Default options should call _printDiffInfo."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args([])
|
||||||
|
|
||||||
|
with mock.patch.object(
|
||||||
|
cmd, "_printDiffInfo"
|
||||||
|
) as mock_diff, mock.patch.object(
|
||||||
|
cmd, "_printCommitOverview"
|
||||||
|
) as mock_overview:
|
||||||
|
cmd.Execute(opts, args)
|
||||||
|
mock_diff.assert_called_once_with(opts, args)
|
||||||
|
mock_overview.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_overview_calls_commit_overview() -> None:
|
||||||
|
"""--overview should call _printCommitOverview, not _printDiffInfo."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(["--overview"])
|
||||||
|
|
||||||
|
with mock.patch.object(
|
||||||
|
cmd, "_printDiffInfo"
|
||||||
|
) as mock_diff, mock.patch.object(
|
||||||
|
cmd, "_printCommitOverview"
|
||||||
|
) as mock_overview:
|
||||||
|
cmd.Execute(opts, args)
|
||||||
|
mock_diff.assert_not_called()
|
||||||
|
mock_overview.assert_called_once_with(opts, args)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_include_projects_with_overview() -> None:
|
||||||
|
"""--no-include-projects should take priority over --overview."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(
|
||||||
|
["--no-include-projects", "--overview"]
|
||||||
|
)
|
||||||
|
|
||||||
|
with mock.patch.object(
|
||||||
|
cmd, "_printDiffInfo"
|
||||||
|
) as mock_diff, mock.patch.object(
|
||||||
|
cmd, "_printCommitOverview"
|
||||||
|
) as mock_overview:
|
||||||
|
cmd.Execute(opts, args)
|
||||||
|
mock_diff.assert_not_called()
|
||||||
|
mock_overview.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_summary_only(capsys) -> None:
|
||||||
|
"""--format=json --no-include-projects should emit only summary."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(
|
||||||
|
["--format=json", "--no-include-projects"]
|
||||||
|
)
|
||||||
|
cmd.Execute(opts, args)
|
||||||
|
data = json.loads(capsys.readouterr().out)
|
||||||
|
assert "summary" in data
|
||||||
|
assert "projects" not in data
|
||||||
|
assert data["summary"]["manifest_branch"] == "refs/heads/main"
|
||||||
|
assert data["summary"]["manifest_groups"] == "all"
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_no_summary(capsys) -> None:
|
||||||
|
"""--format=json --no-include-summary should omit summary."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(
|
||||||
|
["--format=json", "--no-include-summary", "--no-include-projects"]
|
||||||
|
)
|
||||||
|
cmd.Execute(opts, args)
|
||||||
|
data = json.loads(capsys.readouterr().out)
|
||||||
|
assert "summary" not in data
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_rejects_diff() -> None:
|
||||||
|
"""--format=json --diff should be rejected."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(["--format=json", "--diff"])
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
cmd.ValidateOptions(opts, args)
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_rejects_overview() -> None:
|
||||||
|
"""--format=json --overview should be rejected."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, args = cmd.OptionParser.parse_args(["--format=json", "--overview"])
|
||||||
|
with pytest.raises(SystemExit):
|
||||||
|
cmd.ValidateOptions(opts, args)
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_disables_pager() -> None:
|
||||||
|
"""--format=json should disable the pager."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, _ = cmd.OptionParser.parse_args(["--format=json"])
|
||||||
|
assert not cmd.WantPager(opts)
|
||||||
|
|
||||||
|
|
||||||
|
def test_text_enables_pager() -> None:
|
||||||
|
"""Default text format should enable the pager."""
|
||||||
|
cmd = _get_cmd()
|
||||||
|
opts, _ = cmd.OptionParser.parse_args([])
|
||||||
|
assert cmd.WantPager(opts)
|
||||||
Reference in New Issue
Block a user