py3: Switch almost all shebang lines to use `python3`.
This causes `upgrade-zulip-from-git`, as well as a no-option run of
`tools/build-release-tarball`, to produce a Zulip install running
Python 3, rather than Python 2. In particular this means that the
virtualenv we create, in which all application code runs, is Python 3.
One shebang line, on `zulip-ec2-configure-interfaces`, explicitly
keeps Python 2, and at least one external ops script, `wal-e`, also
still runs on Python 2. See discussion on the respective previous
commits that made those explicit. There may also be some other
third-party scripts we use, outside of this source tree and running
outside our virtualenv, that still run on Python 2.
2017-08-02 23:15:16 +02:00
|
|
|
#!/usr/bin/env python3
|
2016-08-29 00:28:59 +02:00
|
|
|
import argparse
|
2017-01-06 15:11:15 +01:00
|
|
|
import logging
|
2021-07-03 08:22:44 +02:00
|
|
|
import os
|
2020-06-11 00:54:34 +02:00
|
|
|
import sys
|
2016-08-02 00:14:01 +02:00
|
|
|
|
2021-07-03 08:22:44 +02:00
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
|
|
|
2017-02-05 21:24:28 +01:00
|
|
|
# check for the venv
|
2021-07-03 08:22:44 +02:00
|
|
|
from tools.lib import sanity_check
|
2020-06-11 00:54:34 +02:00
|
|
|
|
2017-02-05 21:24:28 +01:00
|
|
|
sanity_check.check_venv(__file__)
|
|
|
|
|
linter_lib: Fix mypy errors.
tools/linter_lib/pyflakes.py:35: error: Argument 3 to "run_pyflakes" has incompatible type "List[Tuple[bytes, bytes]]"; expected "List[Tuple[str, str]]"
tools/linter_lib/custom_check.py:110: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:519: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:706: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:728: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:738: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:803: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:805: error: Unsupported operand types for + ("List[Rule]" and "List[Dict[str, Any]]")
tools/linter_lib/custom_check.py:819: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
These were missed the `zulint` package was missing PEP 561 type
annotation markers, and if it’d had them, mypy daemon mode would’ve
required us to set `follow_imports = skip` for it.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-08-07 03:29:33 +02:00
|
|
|
from typing import Dict, Iterable, List
|
2013-10-25 23:46:02 +02:00
|
|
|
|
2020-06-11 00:54:34 +02:00
|
|
|
from zulint import lister
|
|
|
|
|
2021-07-03 08:22:44 +02:00
|
|
|
from tools.lib.html_branches import build_id_dict
|
|
|
|
from tools.lib.pretty_print import validate_indent_html
|
|
|
|
from tools.lib.template_parser import validate
|
|
|
|
|
2017-01-06 15:11:15 +01:00
|
|
|
EXCLUDED_FILES = [
|
|
|
|
## Test data Files for testing modules in tests
|
|
|
|
"tools/tests/test_template_data",
|
2018-11-13 17:50:56 +01:00
|
|
|
# Our parser doesn't handle the way its conditionals are layered
|
2021-02-12 08:20:45 +01:00
|
|
|
"templates/zerver/emails/missed_message.source.html",
|
2019-07-13 07:49:51 +02:00
|
|
|
# Previously unchecked and our parser doesn't like its indentation
|
2021-02-12 08:20:45 +01:00
|
|
|
"static/assets/icons/template.hbs",
|
2021-06-30 22:34:12 +02:00
|
|
|
# The parser does not like the indentation of custom ReadTheDocs templates
|
|
|
|
"docs/_templates/layout.html",
|
2017-01-06 15:11:15 +01:00
|
|
|
]
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
python: Convert function type annotations to Python 3 style.
Generated by com2ann (slightly patched to avoid also converting
assignment type annotations, which require Python 3.6), followed by
some manual whitespace adjustment, and six fixes for runtime issues:
- def __init__(self, token: Token, parent: Optional[Node]) -> None:
+ def __init__(self, token: Token, parent: "Optional[Node]") -> None:
-def main(options: argparse.Namespace) -> NoReturn:
+def main(options: argparse.Namespace) -> "NoReturn":
-def fetch_request(url: str, callback: Any, **kwargs: Any) -> Generator[Callable[..., Any], Any, None]:
+def fetch_request(url: str, callback: Any, **kwargs: Any) -> "Generator[Callable[..., Any], Any, None]":
-def assert_server_running(server: subprocess.Popen[bytes], log_file: Optional[str]) -> None:
+def assert_server_running(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> None:
-def server_is_up(server: subprocess.Popen[bytes], log_file: Optional[str]) -> bool:
+def server_is_up(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> bool:
- method_kwarg_pairs: List[FuncKwargPair],
+ method_kwarg_pairs: "List[FuncKwargPair]",
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-19 03:48:37 +02:00
|
|
|
def check_our_files(modified_only: bool, all_dups: bool, fix: bool, targets: List[str]) -> None:
|
linter_lib: Fix mypy errors.
tools/linter_lib/pyflakes.py:35: error: Argument 3 to "run_pyflakes" has incompatible type "List[Tuple[bytes, bytes]]"; expected "List[Tuple[str, str]]"
tools/linter_lib/custom_check.py:110: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:519: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:706: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:728: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:738: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:803: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:805: error: Unsupported operand types for + ("List[Rule]" and "List[Dict[str, Any]]")
tools/linter_lib/custom_check.py:819: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
These were missed the `zulint` package was missing PEP 561 type
annotation markers, and if it’d had them, mypy daemon mode would’ve
required us to set `follow_imports = skip` for it.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-08-07 03:29:33 +02:00
|
|
|
by_lang = lister.list_files(
|
|
|
|
targets=targets,
|
2021-08-14 01:01:37 +02:00
|
|
|
modified_only=modified_only,
|
2021-02-12 08:20:45 +01:00
|
|
|
ftypes=["hbs", "html"],
|
2021-02-12 08:19:30 +01:00
|
|
|
group_by_ftype=True,
|
|
|
|
exclude=EXCLUDED_FILES,
|
linter_lib: Fix mypy errors.
tools/linter_lib/pyflakes.py:35: error: Argument 3 to "run_pyflakes" has incompatible type "List[Tuple[bytes, bytes]]"; expected "List[Tuple[str, str]]"
tools/linter_lib/custom_check.py:110: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:214: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:502: error: Argument "shebang_rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:519: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:706: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:728: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:738: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
tools/linter_lib/custom_check.py:779: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:803: error: Argument "length_exclude" to "RuleList" has incompatible type "Set[str]"; expected "List[str]"
tools/linter_lib/custom_check.py:805: error: Unsupported operand types for + ("List[Rule]" and "List[Dict[str, Any]]")
tools/linter_lib/custom_check.py:819: error: Argument "rules" to "RuleList" has incompatible type "List[Dict[str, Any]]"; expected "List[Rule]"
These were missed the `zulint` package was missing PEP 561 type
annotation markers, and if it’d had them, mypy daemon mode would’ve
required us to set `follow_imports = skip` for it.
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2019-08-07 03:29:33 +02:00
|
|
|
)
|
2013-10-25 20:47:03 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
check_handlebar_templates(by_lang["hbs"], fix)
|
|
|
|
check_html_templates(by_lang["html"], all_dups, fix)
|
2013-11-18 22:57:55 +01:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
python: Convert function type annotations to Python 3 style.
Generated by com2ann (slightly patched to avoid also converting
assignment type annotations, which require Python 3.6), followed by
some manual whitespace adjustment, and six fixes for runtime issues:
- def __init__(self, token: Token, parent: Optional[Node]) -> None:
+ def __init__(self, token: Token, parent: "Optional[Node]") -> None:
-def main(options: argparse.Namespace) -> NoReturn:
+def main(options: argparse.Namespace) -> "NoReturn":
-def fetch_request(url: str, callback: Any, **kwargs: Any) -> Generator[Callable[..., Any], Any, None]:
+def fetch_request(url: str, callback: Any, **kwargs: Any) -> "Generator[Callable[..., Any], Any, None]":
-def assert_server_running(server: subprocess.Popen[bytes], log_file: Optional[str]) -> None:
+def assert_server_running(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> None:
-def server_is_up(server: subprocess.Popen[bytes], log_file: Optional[str]) -> bool:
+def server_is_up(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> bool:
- method_kwarg_pairs: List[FuncKwargPair],
+ method_kwarg_pairs: "List[FuncKwargPair]",
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-19 03:48:37 +02:00
|
|
|
def check_html_templates(templates: Iterable[str], all_dups: bool, fix: bool) -> None:
|
2016-07-09 02:43:32 +02:00
|
|
|
# Our files with .html extensions are usually for Django, but we also
|
2016-07-12 21:28:08 +02:00
|
|
|
# have a few static .html files.
|
2021-02-12 08:20:45 +01:00
|
|
|
logging.basicConfig(format="%(levelname)s:%(message)s")
|
2020-08-31 00:10:57 +02:00
|
|
|
templates = sorted(fn for fn in templates)
|
2020-07-25 02:02:35 +02:00
|
|
|
# Use of lodash templates <%= %>.
|
2021-02-12 08:20:45 +01:00
|
|
|
if "templates/zerver/team.html" in templates:
|
|
|
|
templates.remove("templates/zerver/team.html")
|
2013-10-25 20:47:03 +02:00
|
|
|
|
2018-04-27 15:04:40 +02:00
|
|
|
def check_for_duplicate_ids(templates: List[str]) -> Dict[str, List[str]]:
|
|
|
|
template_id_dict = build_id_dict(templates)
|
|
|
|
# TODO: Clean up these cases of duplicate ids in the code
|
|
|
|
IGNORE_IDS = [
|
2021-02-12 08:20:45 +01:00
|
|
|
"api-example-tabs",
|
|
|
|
"errors",
|
|
|
|
"error-message-box",
|
|
|
|
"email",
|
|
|
|
"messages",
|
|
|
|
"registration",
|
|
|
|
"pw_strength",
|
|
|
|
"id_password",
|
|
|
|
"top_navbar",
|
|
|
|
"id_email",
|
|
|
|
"id_terms",
|
2021-06-10 22:12:23 +02:00
|
|
|
"logout_form",
|
2021-02-12 08:20:45 +01:00
|
|
|
"send_confirm",
|
|
|
|
"register",
|
|
|
|
"footer",
|
|
|
|
"charged_amount",
|
|
|
|
"change-plan-status",
|
2018-07-14 11:39:33 +02:00
|
|
|
# Temporary while we have searchbox forked
|
2021-02-12 08:20:45 +01:00
|
|
|
"search_exit",
|
|
|
|
"search_query",
|
|
|
|
"message_view_header",
|
|
|
|
"search_arrows",
|
|
|
|
"searchbox_form",
|
|
|
|
"searchbox",
|
2018-04-27 15:04:40 +02:00
|
|
|
]
|
2021-02-12 08:19:30 +01:00
|
|
|
bad_ids_dict = {
|
|
|
|
ids: fns
|
|
|
|
for ids, fns in template_id_dict.items()
|
|
|
|
if (ids not in IGNORE_IDS) and len(fns) > 1
|
|
|
|
}
|
2017-01-06 15:11:15 +01:00
|
|
|
|
2018-04-27 15:04:40 +02:00
|
|
|
if all_dups:
|
2021-02-12 08:19:30 +01:00
|
|
|
ignorable_ids_dict = {
|
|
|
|
ids: fns
|
|
|
|
for ids, fns in template_id_dict.items()
|
|
|
|
if ids in IGNORE_IDS and len(fns) > 1
|
|
|
|
}
|
2017-01-06 15:11:15 +01:00
|
|
|
|
2018-04-27 15:04:40 +02:00
|
|
|
for ids, fns in ignorable_ids_dict.items():
|
2021-02-12 08:19:30 +01:00
|
|
|
logging.warning(
|
|
|
|
"Duplicate ID(s) detected :Id '" + ids + "' present at following files:"
|
|
|
|
)
|
2018-04-27 15:04:40 +02:00
|
|
|
for fn in fns:
|
|
|
|
print(fn)
|
|
|
|
|
|
|
|
for ids, fns in bad_ids_dict.items():
|
2021-02-12 08:19:30 +01:00
|
|
|
logging.error("Duplicate ID(s) detected :Id '" + ids + "' present at following files:")
|
2017-01-06 15:11:15 +01:00
|
|
|
for fn in fns:
|
|
|
|
print(fn)
|
2018-04-27 15:04:40 +02:00
|
|
|
return bad_ids_dict
|
|
|
|
|
2021-07-27 22:45:06 +02:00
|
|
|
bad_ids_list = list(check_for_duplicate_ids(templates).keys())
|
2017-01-06 15:11:15 +01:00
|
|
|
|
2018-04-27 15:04:40 +02:00
|
|
|
if bad_ids_list:
|
2021-02-12 08:20:45 +01:00
|
|
|
print("Exiting--please clean up all duplicates before running this again.")
|
2017-01-06 15:11:15 +01:00
|
|
|
sys.exit(1)
|
|
|
|
|
2014-02-27 16:41:47 +01:00
|
|
|
for fn in templates:
|
2016-07-12 22:32:36 +02:00
|
|
|
# Many of our Django templates have strange indentation. The
|
|
|
|
# indentation errors are often harmless, even stylistically
|
|
|
|
# harmless, but they tend to be in files that might be old
|
|
|
|
# and might eventually require more scrutiny for things like
|
2020-10-23 02:43:28 +02:00
|
|
|
# localization. See GitHub #1236.
|
2016-07-12 22:32:36 +02:00
|
|
|
bad_files = [
|
2017-10-20 01:54:07 +02:00
|
|
|
# These use various whitespace-dependent formatting that
|
|
|
|
# prevent cleaning them.
|
2021-02-12 08:20:45 +01:00
|
|
|
"templates/corporate/zephyr-mirror.html",
|
2016-07-12 22:32:36 +02:00
|
|
|
]
|
2016-08-04 01:44:15 +02:00
|
|
|
validate(fn=fn, check_indent=(fn not in bad_files))
|
2014-02-27 16:41:47 +01:00
|
|
|
|
2017-03-12 22:24:26 +01:00
|
|
|
# Ignore these files since these have not been cleaned yet :/
|
|
|
|
IGNORE_FILES = [
|
2018-01-28 00:17:28 +01:00
|
|
|
# zephyr-mirror.html has some whitespace-dependent formatting
|
|
|
|
# for code blocks that prevent cleaning it. Might make sense
|
2020-08-11 01:47:49 +02:00
|
|
|
# to convert it to a /help/ Markdown article.
|
2021-02-12 08:20:45 +01:00
|
|
|
"templates/corporate/zephyr-mirror.html",
|
2017-03-12 22:24:26 +01:00
|
|
|
]
|
|
|
|
# TODO: Clean these files
|
|
|
|
for fn in templates:
|
|
|
|
if fn not in IGNORE_FILES:
|
2019-07-18 02:41:47 +02:00
|
|
|
if not validate_indent_html(fn, fix):
|
2017-03-12 22:24:26 +01:00
|
|
|
sys.exit(1)
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
python: Convert function type annotations to Python 3 style.
Generated by com2ann (slightly patched to avoid also converting
assignment type annotations, which require Python 3.6), followed by
some manual whitespace adjustment, and six fixes for runtime issues:
- def __init__(self, token: Token, parent: Optional[Node]) -> None:
+ def __init__(self, token: Token, parent: "Optional[Node]") -> None:
-def main(options: argparse.Namespace) -> NoReturn:
+def main(options: argparse.Namespace) -> "NoReturn":
-def fetch_request(url: str, callback: Any, **kwargs: Any) -> Generator[Callable[..., Any], Any, None]:
+def fetch_request(url: str, callback: Any, **kwargs: Any) -> "Generator[Callable[..., Any], Any, None]":
-def assert_server_running(server: subprocess.Popen[bytes], log_file: Optional[str]) -> None:
+def assert_server_running(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> None:
-def server_is_up(server: subprocess.Popen[bytes], log_file: Optional[str]) -> bool:
+def server_is_up(server: "subprocess.Popen[bytes]", log_file: Optional[str]) -> bool:
- method_kwarg_pairs: List[FuncKwargPair],
+ method_kwarg_pairs: "List[FuncKwargPair]",
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-19 03:48:37 +02:00
|
|
|
def check_handlebar_templates(templates: Iterable[str], fix: bool) -> None:
|
2016-08-02 00:14:01 +02:00
|
|
|
# Check all our handlebars templates.
|
2021-02-12 08:20:45 +01:00
|
|
|
templates = [fn for fn in templates if fn.endswith(".hbs")]
|
2017-08-28 07:01:00 +02:00
|
|
|
|
2016-08-02 00:14:01 +02:00
|
|
|
for fn in templates:
|
2016-08-04 01:44:15 +02:00
|
|
|
validate(fn=fn, check_indent=True)
|
2016-08-02 00:14:01 +02:00
|
|
|
|
2017-03-12 22:24:26 +01:00
|
|
|
for fn in templates:
|
2019-07-18 02:41:47 +02:00
|
|
|
if not validate_indent_html(fn, fix):
|
2017-05-12 17:17:05 +02:00
|
|
|
sys.exit(1)
|
2017-03-12 22:24:26 +01:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
if __name__ == "__main__":
|
2017-03-19 20:59:22 +01:00
|
|
|
parser = argparse.ArgumentParser()
|
2021-02-12 08:20:45 +01:00
|
|
|
parser.add_argument("-m", "--modified", action="store_true", help="only check modified files")
|
2021-02-12 08:19:30 +01:00
|
|
|
parser.add_argument(
|
2021-02-12 08:20:45 +01:00
|
|
|
"--all-dups",
|
2021-02-12 08:19:30 +01:00
|
|
|
action="store_true",
|
2021-02-12 08:20:45 +01:00
|
|
|
help="Run lint tool to detect duplicate ids on ignored files as well",
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
|
|
|
parser.add_argument(
|
2021-02-12 08:20:45 +01:00
|
|
|
"--fix", action="store_true", help="Automatically fix indentation problems."
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
parser.add_argument("targets", nargs=argparse.REMAINDER)
|
2017-03-19 20:59:22 +01:00
|
|
|
args = parser.parse_args()
|
2019-07-18 02:41:47 +02:00
|
|
|
check_our_files(args.modified, args.all_dups, args.fix, args.targets)
|