forked from extern/httpie-cli
Man page clean-up (#1508)
Ensure we don’t include dynamic content in the static man pages.
This commit is contained in:
parent
c2677eeccf
commit
2da955fb06
@ -1,27 +1,22 @@
|
|||||||
name: Update Autogenerated Files
|
name: Update Generated Content
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
regen-autogenerated-files:
|
update-content:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: 3.9
|
python-version: 3.9
|
||||||
|
- run: make content
|
||||||
- run: make regen-all
|
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
id: cpr
|
id: cpr
|
||||||
uses: peter-evans/create-pull-request@v4
|
uses: peter-evans/create-pull-request@v4
|
||||||
with:
|
with:
|
||||||
commit-message: "[automated] Update auto-generated files"
|
commit-message: "[automated] Update generated content"
|
||||||
title: "[automated] Update auto-generated files"
|
title: "[automated] Update generated content"
|
||||||
delete-branch: true
|
delete-branch: true
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
8
Makefile
8
Makefile
@ -231,15 +231,15 @@ brew-test:
|
|||||||
brew audit --strict httpie
|
brew audit --strict httpie
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Regeneration
|
# Generated content
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
regen-all: regen-man-pages regen-install-methods
|
content: man installation-docs
|
||||||
|
|
||||||
regen-man-pages: install
|
man: install
|
||||||
@echo $(H1)Regenerate man pages$(H1END)
|
@echo $(H1)Regenerate man pages$(H1END)
|
||||||
$(VENV_PYTHON) extras/scripts/generate_man_pages.py
|
$(VENV_PYTHON) extras/scripts/generate_man_pages.py
|
||||||
|
|
||||||
regen-install-methods:
|
installation-docs:
|
||||||
@echo $(H1)Updating installation instructions in the docs$(H1END)
|
@echo $(H1)Updating installation instructions in the docs$(H1END)
|
||||||
$(VENV_PYTHON) docs/installation/generate.py
|
$(VENV_PYTHON) docs/installation/generate.py
|
||||||
|
@ -399,7 +399,7 @@ The authentication mechanism to be used. Defaults to \[dq]basic\[dq].
|
|||||||
|
|
||||||
\[dq]bearer\[dq]: Bearer HTTP Auth
|
\[dq]bearer\[dq]: Bearer HTTP Auth
|
||||||
|
|
||||||
For finding out all available authentication types in your system, try:
|
To see all available auth types on your system, including ones installed via plugins, run:
|
||||||
|
|
||||||
$ http \fB\,--auth-type\/\fR
|
$ http \fB\,--auth-type\/\fR
|
||||||
|
|
||||||
@ -510,11 +510,10 @@ are shown here).
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
A string in the OpenSSL cipher list format. By default, the following
|
A string in the OpenSSL cipher list format.
|
||||||
ciphers are used on your system:
|
|
||||||
|
|
||||||
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA
|
|
||||||
|
|
||||||
|
See `http \fB\,--help\/\fR` for the default ciphers list on you system.
|
||||||
|
|
||||||
|
|
||||||
.IP "\fB\,--cert\/\fR"
|
.IP "\fB\,--cert\/\fR"
|
||||||
|
@ -399,7 +399,7 @@ The authentication mechanism to be used. Defaults to \[dq]basic\[dq].
|
|||||||
|
|
||||||
\[dq]bearer\[dq]: Bearer HTTP Auth
|
\[dq]bearer\[dq]: Bearer HTTP Auth
|
||||||
|
|
||||||
For finding out all available authentication types in your system, try:
|
To see all available auth types on your system, including ones installed via plugins, run:
|
||||||
|
|
||||||
$ http \fB\,--auth-type\/\fR
|
$ http \fB\,--auth-type\/\fR
|
||||||
|
|
||||||
@ -509,12 +509,10 @@ are shown here).
|
|||||||
.IP "\fB\,--ciphers\/\fR"
|
.IP "\fB\,--ciphers\/\fR"
|
||||||
|
|
||||||
|
|
||||||
|
A string in the OpenSSL cipher list format.
|
||||||
|
|
||||||
A string in the OpenSSL cipher list format. By default, the following
|
|
||||||
ciphers are used on your system:
|
|
||||||
|
|
||||||
TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA
|
|
||||||
|
|
||||||
|
See `http \fB\,--help\/\fR` for the default ciphers list on you system.
|
||||||
|
|
||||||
|
|
||||||
.IP "\fB\,--cert\/\fR"
|
.IP "\fB\,--cert\/\fR"
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
|
import os
|
||||||
import re
|
import re
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional, Iterator, Iterable
|
from typing import Optional, Iterator, Iterable
|
||||||
|
|
||||||
|
|
||||||
|
# So that httpie.cli.definition can provide man-page-specific output. Must be set before importing httpie.
|
||||||
|
os.environ['HTTPIE_BUILDING_MAN_PAGES'] = '1'
|
||||||
|
|
||||||
import httpie
|
import httpie
|
||||||
from httpie.cli.definition import options as core_options
|
from httpie.cli.definition import options as core_options, IS_MAN_PAGE
|
||||||
from httpie.cli.options import ParserSpec
|
from httpie.cli.options import ParserSpec
|
||||||
from httpie.manager.cli import options as manager_options
|
from httpie.manager.cli import options as manager_options
|
||||||
from httpie.output.ui.rich_help import OptionsHighlighter, to_usage
|
from httpie.output.ui.rich_help import OptionsHighlighter, to_usage
|
||||||
from httpie.output.ui.rich_utils import render_as_string
|
from httpie.output.ui.rich_utils import render_as_string
|
||||||
from httpie.utils import split_iterable
|
|
||||||
|
|
||||||
|
|
||||||
# Escape certain characters so they are rendered properly on
|
assert IS_MAN_PAGE, 'CLI definition does not understand we’re building man pages'
|
||||||
# all terminals.
|
|
||||||
# https://man7.org/linux/man-pages/man7/groff_char.7.html
|
# Escape certain characters, so they are rendered properly on all terminals.
|
||||||
|
# <https://man7.org/linux/man-pages/man7/groff_char.7.html>
|
||||||
ESCAPE_MAP = {
|
ESCAPE_MAP = {
|
||||||
'"': '\[dq]',
|
'"': '\[dq]',
|
||||||
"'": '\[aq]',
|
"'": '\[aq]',
|
||||||
@ -32,6 +37,7 @@ OPTION_HIGHLIGHT_RE = re.compile(
|
|||||||
OptionsHighlighter.highlights[0]
|
OptionsHighlighter.highlights[0]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ManPageBuilder:
|
class ManPageBuilder:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.source = []
|
self.source = []
|
||||||
@ -125,7 +131,7 @@ def to_man_page(program_name: str, spec: ParserSpec, *, is_top_level_cmd: bool =
|
|||||||
|
|
||||||
with builder.section('SYNOPSIS'):
|
with builder.section('SYNOPSIS'):
|
||||||
# `http` and `https` are commands that can be directly used, so they can have
|
# `http` and `https` are commands that can be directly used, so they can have
|
||||||
# have a valid usage. But `httpie` is a top-level command with multiple sub commands,
|
# a valid usage. But `httpie` is a top-level command with multiple sub commands,
|
||||||
# so for the synopsis we'll only reference the `httpie` name.
|
# so for the synopsis we'll only reference the `httpie` name.
|
||||||
if is_top_level_cmd:
|
if is_top_level_cmd:
|
||||||
synopsis = program_name
|
synopsis = program_name
|
||||||
@ -153,7 +159,7 @@ def to_man_page(program_name: str, spec: ParserSpec, *, is_top_level_cmd: bool =
|
|||||||
if raw_arg.get('is_positional'):
|
if raw_arg.get('is_positional'):
|
||||||
# In case of positional arguments, metavar is always equal
|
# In case of positional arguments, metavar is always equal
|
||||||
# to the list of options (e.g `METHOD`).
|
# to the list of options (e.g `METHOD`).
|
||||||
metavar = None
|
metavar = None
|
||||||
builder.add_options(raw_arg['options'], metavar=metavar)
|
builder.add_options(raw_arg['options'], metavar=metavar)
|
||||||
|
|
||||||
desc = builder.format_desc(raw_arg.get('description', ''))
|
desc = builder.format_desc(raw_arg.get('description', ''))
|
||||||
@ -178,6 +184,5 @@ def main() -> None:
|
|||||||
stream.write(to_man_page(program_name, spec, **config))
|
stream.write(to_man_page(program_name, spec, **config))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import os
|
||||||
import textwrap
|
import textwrap
|
||||||
from argparse import FileType
|
from argparse import FileType
|
||||||
|
|
||||||
@ -22,6 +23,12 @@ from httpie.plugins.builtin import BuiltinAuthPlugin
|
|||||||
from httpie.plugins.registry import plugin_manager
|
from httpie.plugins.registry import plugin_manager
|
||||||
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS_STRING
|
from httpie.ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, DEFAULT_SSL_CIPHERS_STRING
|
||||||
|
|
||||||
|
|
||||||
|
# Man pages are static (built when making a release).
|
||||||
|
# We use this check to not include generated, system-specific information there (e.g., default --ciphers).
|
||||||
|
IS_MAN_PAGE = bool(os.environ.get('HTTPIE_BUILDING_MAN_PAGES'))
|
||||||
|
|
||||||
|
|
||||||
options = ParserSpec(
|
options = ParserSpec(
|
||||||
'http',
|
'http',
|
||||||
description=f'{__doc__.strip()} <https://httpie.io>',
|
description=f'{__doc__.strip()} <https://httpie.io>',
|
||||||
@ -35,7 +42,6 @@ options = ParserSpec(
|
|||||||
source_file=__file__
|
source_file=__file__
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# Positional arguments.
|
# Positional arguments.
|
||||||
#######################################################################
|
#######################################################################
|
||||||
@ -234,6 +240,7 @@ processing_options.add_argument(
|
|||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# Output processing
|
# Output processing
|
||||||
#######################################################################
|
#######################################################################
|
||||||
@ -610,6 +617,7 @@ sessions.add_argument(
|
|||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#######################################################################
|
#######################################################################
|
||||||
# Authentication
|
# Authentication
|
||||||
#######################################################################
|
#######################################################################
|
||||||
@ -630,7 +638,7 @@ def format_auth_help(auth_plugins_mapping, *, isolation_mode: bool = False):
|
|||||||
if issubclass(auth_plugin, BuiltinAuthPlugin)
|
if issubclass(auth_plugin, BuiltinAuthPlugin)
|
||||||
]
|
]
|
||||||
text += '\n'
|
text += '\n'
|
||||||
text += 'For finding out all available authentication types in your system, try:\n\n'
|
text += 'To see all available auth types on your system, including ones installed via plugins, run:\n\n'
|
||||||
text += ' $ http --auth-type'
|
text += ' $ http --auth-type'
|
||||||
|
|
||||||
auth_types = '\n\n '.join(
|
auth_types = '\n\n '.join(
|
||||||
@ -646,7 +654,7 @@ def format_auth_help(auth_plugins_mapping, *, isolation_mode: bool = False):
|
|||||||
''
|
''
|
||||||
if not plugin.description
|
if not plugin.description
|
||||||
else '\n '
|
else '\n '
|
||||||
+ ('\n '.join(textwrap.wrap(plugin.description)))
|
+ ('\n '.join(textwrap.wrap(plugin.description)))
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
for plugin in auth_plugins
|
for plugin in auth_plugins
|
||||||
@ -826,23 +834,36 @@ ssl.add_argument(
|
|||||||
|
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CIPHERS_CURRENT_DEFAULTS = (
|
||||||
|
"""
|
||||||
|
See `http --help` for the default ciphers list on you system.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if IS_MAN_PAGE else
|
||||||
|
f"""
|
||||||
|
By default, the following ciphers are used on your system:
|
||||||
|
|
||||||
|
{DEFAULT_SSL_CIPHERS_STRING}
|
||||||
|
|
||||||
|
"""
|
||||||
|
)
|
||||||
ssl.add_argument(
|
ssl.add_argument(
|
||||||
'--ciphers',
|
'--ciphers',
|
||||||
short_help='A string in the OpenSSL cipher list format.',
|
short_help='A string in the OpenSSL cipher list format.',
|
||||||
help=f"""
|
help=f"""
|
||||||
|
|
||||||
A string in the OpenSSL cipher list format. By default, the following
|
A string in the OpenSSL cipher list format.
|
||||||
ciphers are used on your system:
|
|
||||||
|
|
||||||
{DEFAULT_SSL_CIPHERS_STRING}
|
{CIPHERS_CURRENT_DEFAULTS}
|
||||||
|
|
||||||
""",
|
"""
|
||||||
)
|
)
|
||||||
ssl.add_argument(
|
ssl.add_argument(
|
||||||
'--cert',
|
'--cert',
|
||||||
default=None,
|
default=None,
|
||||||
type=readable_file_arg,
|
type=readable_file_arg,
|
||||||
short_help='Specifys a local cert to use as client side SSL certificate.',
|
short_help='Specifies a local cert to use as the client-side SSL certificate.',
|
||||||
help="""
|
help="""
|
||||||
You can specify a local cert to use as client side SSL certificate.
|
You can specify a local cert to use as client side SSL certificate.
|
||||||
This file may either contain both private key and certificate or you may
|
This file may either contain both private key and certificate or you may
|
||||||
|
@ -4,23 +4,22 @@ import subprocess
|
|||||||
import os
|
import os
|
||||||
from httpie.context import Environment
|
from httpie.context import Environment
|
||||||
|
|
||||||
|
|
||||||
MAN_COMMAND = 'man'
|
MAN_COMMAND = 'man'
|
||||||
NO_MAN_PAGES = os.getenv('HTTPIE_NO_MAN_PAGES', False)
|
NO_MAN_PAGES = os.getenv('HTTPIE_NO_MAN_PAGES', False)
|
||||||
|
|
||||||
# On some systems, HTTP(n) might exist but we are only
|
# On some systems, HTTP(n) might exist, but we are only interested in HTTP(1).
|
||||||
# interested in HTTP(1).
|
# For more information on man page sections: <https://unix.stackexchange.com/a/138643>
|
||||||
#
|
|
||||||
# For more information on man page sections: https://unix.stackexchange.com/a/138643
|
|
||||||
|
|
||||||
MAN_PAGE_SECTION = '1'
|
MAN_PAGE_SECTION = '1'
|
||||||
|
|
||||||
|
|
||||||
def is_available(program: str) -> bool:
|
def is_available(program: str) -> bool:
|
||||||
"""Check whether HTTPie's man pages are available in this system."""
|
"""
|
||||||
|
Check whether `program`'s man pages are available on this system.
|
||||||
|
|
||||||
|
"""
|
||||||
if NO_MAN_PAGES or os.system == 'nt':
|
if NO_MAN_PAGES or os.system == 'nt':
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
process = subprocess.run(
|
process = subprocess.run(
|
||||||
[MAN_COMMAND, MAN_PAGE_SECTION, program],
|
[MAN_COMMAND, MAN_PAGE_SECTION, program],
|
||||||
@ -29,7 +28,7 @@ def is_available(program: str) -> bool:
|
|||||||
stderr=subprocess.DEVNULL
|
stderr=subprocess.DEVNULL
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
# There might be some errors outside of the process, e.g
|
# There might be some errors outside the process, e.g
|
||||||
# a permission error to execute something that is not an
|
# a permission error to execute something that is not an
|
||||||
# executable.
|
# executable.
|
||||||
return False
|
return False
|
||||||
@ -38,8 +37,10 @@ def is_available(program: str) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def display_for(env: Environment, program: str) -> None:
|
def display_for(env: Environment, program: str) -> None:
|
||||||
"""Display the man page for the given command (http/https)."""
|
"""
|
||||||
|
Open the system man page for the given command (http/https/httpie).
|
||||||
|
|
||||||
|
"""
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
[MAN_COMMAND, MAN_PAGE_SECTION, program],
|
[MAN_COMMAND, MAN_PAGE_SECTION, program],
|
||||||
stdout=env.stdout,
|
stdout=env.stdout,
|
||||||
|
Loading…
Reference in New Issue
Block a user