Bug 1951578: remove mach pastebin. r=sergesanspaille

Adds a new "hidden" argument to mach decorators that allows the command to
execute but will not be visible in `mach help`.

Removes `mach pastebin` functionality, marks it as "hidden", and displays a
notice that pastebin.mozilla.org has been decommissioned.

Differential Revision: https://phabricator.services.mozilla.com/D240280
This commit is contained in:
glob
2025-03-10 08:13:03 +00:00
parent 663dde8838
commit 6f12c82f07
6 changed files with 70 additions and 231 deletions

View File

@@ -45,6 +45,8 @@ class _MachCommand:
"decl_order",
# Whether to disable automatic logging to last_log.json for the command.
"no_auto_log",
# Whether to hide this command from help.
"hidden",
)
def __init__(
@@ -59,6 +61,7 @@ class _MachCommand:
virtualenv_name=None,
ok_if_tests_disabled=False,
no_auto_log=False,
hidden=False,
):
self.name = name
self.subcommand = subcommand
@@ -70,6 +73,7 @@ class _MachCommand:
self.argument_group_names = []
self.virtualenv_name = virtualenv_name
self.order = order
self.hidden = hidden
if ok_if_tests_disabled and category != "testing":
raise ValueError(
"ok_if_tests_disabled should only be set for " "`testing` mach commands"

View File

@@ -259,6 +259,9 @@ class CommandAction(argparse.Action):
for command in sorted(r.commands_by_category[category]):
handler = r.command_handlers[command]
if handler.hidden:
continue
# Instantiate a handler class to see if it should be filtered
# out for the current context or not. Condition functions can be
# applied to the command's decorator.

View File

@@ -0,0 +1,20 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from mach.decorators import Command
@Command("cmd_default_visible", category="testing")
def run_default_visible(self, command_context):
pass
@Command("cmd_not_hidden", category="testing")
def run_not_hidden(self, command_context, hidden=False):
pass
@Command("cmd_hidden", category="testing", hidden=True)
def run_hidden(self, command_context):
pass

View File

@@ -6,6 +6,8 @@ subsuite = "mach"
["test_conditions.py"]
skip-if = ["true"]
["test_definitions.py"]
["test_config.py"]
["test_decorators.py"]

View File

@@ -0,0 +1,28 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from pathlib import Path
from mozunit import main
from mach.test.conftest import TestBase
class TestConditions(TestBase):
"""Tests for definitions provided to the @Command decorator."""
def _run(self, args):
return self._run_mach(args, Path("definitions.py"))
def test_help_message(self):
"""Test that commands that are hidden do not show up in help."""
result, stdout, stderr = self._run(["help"])
self.assertIn("cmd_default_visible", stdout)
self.assertIn("cmd_not_hidden", stdout)
self.assertNotIn("cmd_hidden", stdout)
if __name__ == "__main__":
main()

View File

@@ -110,246 +110,28 @@ def busted_file(command_context, against):
webbrowser.open_new_tab(uri)
MACH_PASTEBIN_DURATIONS = {
"onetime": "onetime",
"hour": "3600",
"day": "86400",
"week": "604800",
"month": "2073600",
}
EXTENSION_TO_HIGHLIGHTER = {
".hgrc": "ini",
"Dockerfile": "docker",
"Makefile": "make",
"applescript": "applescript",
"arduino": "arduino",
"bash": "bash",
"bat": "bat",
"c": "c",
"clojure": "clojure",
"cmake": "cmake",
"coffee": "coffee-script",
"console": "console",
"cpp": "cpp",
"cs": "csharp",
"css": "css",
"cu": "cuda",
"cuda": "cuda",
"dart": "dart",
"delphi": "delphi",
"diff": "diff",
"django": "django",
"docker": "docker",
"elixir": "elixir",
"erlang": "erlang",
"go": "go",
"h": "c",
"handlebars": "handlebars",
"haskell": "haskell",
"hs": "haskell",
"html": "html",
"ini": "ini",
"ipy": "ipythonconsole",
"ipynb": "ipythonconsole",
"irc": "irc",
"j2": "django",
"java": "java",
"js": "js",
"json": "json",
"jsx": "jsx",
"kt": "kotlin",
"less": "less",
"lisp": "common-lisp",
"lsp": "common-lisp",
"lua": "lua",
"m": "objective-c",
"make": "make",
"matlab": "matlab",
"md": "_markdown",
"nginx": "nginx",
"numpy": "numpy",
"patch": "diff",
"perl": "perl",
"php": "php",
"pm": "perl",
"postgresql": "postgresql",
"py": "python",
"rb": "rb",
"rs": "rust",
"rst": "rst",
"sass": "sass",
"scss": "scss",
"sh": "bash",
"sol": "sol",
"sql": "sql",
"swift": "swift",
"tex": "tex",
"typoscript": "typoscript",
"vim": "vim",
"xml": "xml",
"xslt": "xslt",
"yaml": "yaml",
"yml": "yaml",
}
def guess_highlighter_from_path(path):
"""Return a known highlighter from a given path
Attempt to select a highlighter by checking the file extension in the mapping
of extensions to highlighter. If that fails, attempt to pass the basename of
the file. Return `_code` as the default highlighter if that fails.
"""
import os
_name, ext = os.path.splitext(path)
if ext.startswith("."):
ext = ext[1:]
if ext in EXTENSION_TO_HIGHLIGHTER:
return EXTENSION_TO_HIGHLIGHTER[ext]
basename = os.path.basename(path)
return EXTENSION_TO_HIGHLIGHTER.get(basename, "_code")
PASTEMO_MAX_CONTENT_LENGTH = 250 * 1024 * 1024
PASTEMO_URL = "https://paste.mozilla.org/api/"
def pastebin_create_parser():
# Accept all args so they can be promptly ignored.
parser = argparse.ArgumentParser()
parser.add_argument("argv", nargs=argparse.REMAINDER, help=argparse.SUPPRESS)
return parser
@Command(
"pastebin",
category="misc",
description="Command line interface to paste.mozilla.org.",
hidden=True,
parser=pastebin_create_parser,
)
@CommandArgument(
"--list-highlighters",
action="store_true",
help="List known highlighters and exit",
)
@CommandArgument(
"--highlighter", default=None, help="Syntax highlighting to use for paste"
)
@CommandArgument(
"--expires",
default="week",
choices=sorted(MACH_PASTEBIN_DURATIONS.keys()),
help="Expire paste after given time duration (default: %(default)s)",
)
@CommandArgument(
"--verbose",
action="store_true",
help="Print extra info such as selected syntax highlighter",
)
@CommandArgument(
"path",
nargs="?",
default=None,
help="Path to file for upload to paste.mozilla.org",
)
def pastebin(command_context, list_highlighters, highlighter, expires, verbose, path):
"""Command line interface to `paste.mozilla.org`.
def pastebin(command_context, argv):
"""Obsolete command line interface to `paste.mozilla.org`."""
Takes either a filename whose content should be pasted, or reads
content from standard input. If a highlighter is specified it will
be used, otherwise the file name will be used to determine an
appropriate highlighter.
"""
import requests
def verbose_print(*args, **kwargs):
"""Print a string if `--verbose` flag is set"""
if verbose:
print(*args, **kwargs)
# Show known highlighters and exit.
if list_highlighters:
lexers = set(EXTENSION_TO_HIGHLIGHTER.values())
print("Available lexers:\n - %s" % "\n - ".join(sorted(lexers)))
return 0
# Get a correct expiry value.
try:
verbose_print("Setting expiry from %s" % expires)
expires = MACH_PASTEBIN_DURATIONS[expires]
verbose_print("Using %s as expiry" % expires)
except KeyError:
print(
"%s is not a valid duration.\n"
"(hint: try one of %s)"
% (expires, ", ".join(MACH_PASTEBIN_DURATIONS.keys()))
"pastebin.mozilla.org has been decommissioned.\n"
"Please use your favorite search engine to find alternatives."
)
return 1
data = {
"format": "json",
"expires": expires,
}
# Get content to be pasted.
if path:
verbose_print("Reading content from %s" % path)
try:
with open(path, "r") as f:
content = f.read()
except IOError:
print("ERROR. No such file %s" % path)
return 1
lexer = guess_highlighter_from_path(path)
if lexer:
data["lexer"] = lexer
else:
verbose_print("Reading content from stdin")
content = sys.stdin.read()
# Assert the length of content to be posted does not exceed the maximum.
content_length = len(content)
verbose_print("Checking size of content is okay (%d)" % content_length)
if content_length > PASTEMO_MAX_CONTENT_LENGTH:
print(
"Paste content is too large (%d, maximum %d)"
% (content_length, PASTEMO_MAX_CONTENT_LENGTH)
)
return 1
data["content"] = content
# Highlight as specified language, overwriting value set from filename.
if highlighter:
verbose_print("Setting %s as highlighter" % highlighter)
data["lexer"] = highlighter
try:
verbose_print("Sending request to %s" % PASTEMO_URL)
resp = requests.post(PASTEMO_URL, data=data)
# Error code should always be 400.
# Response content will include a helpful error message,
# so print it here (for example, if an invalid highlighter is
# provided, it will return a list of valid highlighters).
if resp.status_code >= 400:
print("Error code %d: %s" % (resp.status_code, resp.content))
return 1
verbose_print("Pasted successfully")
response_json = resp.json()
verbose_print("Paste highlighted as %s" % response_json["lexer"])
print(response_json["url"])
return 0
except Exception as e:
print("ERROR. Paste failed.")
print("%s" % e)
return 1
class PypiBasedTool:
"""