Compare commits
5 Commits
5c7f2b7154
...
69c48d613c
Author | SHA1 | Date |
---|---|---|
Julien Palard | 69c48d613c | |
Christophe Nanteuil | 86263ffcba | |
Christophe Nanteuil | b39636c907 | |
Christophe Nanteuil | f790dbb2f7 | |
Julien Palard | e08a750ef7 |
10
README.md
10
README.md
|
@ -13,15 +13,19 @@ and `pogrep` is a part of it! Go check out [Poutils](https://pypi.org/project/po
|
|||
Print usage: `pogrep --help`
|
||||
|
||||
Find how 'flavors' has already been translated: search recursively in the
|
||||
current directory, show the names of the matching files, excluding the venv
|
||||
directory which contains a virtual env:
|
||||
current directory, show the names of the matching files, excluding the venv and the
|
||||
locales directories which are not relevant:
|
||||
|
||||
`pogrep --recursive --line-number --exclude-dir venv flavor `
|
||||
`pogrep --recursive --line-number --exclude-dir venv --exclude-dir locales flavor `
|
||||
|
||||
Search the word 'typo' in traductions, but not in sources:
|
||||
|
||||
`pogrep --recursive --translation --no-source --word-regexp typo `
|
||||
|
||||
Blame usage of 'allogène' in traductions:
|
||||
|
||||
`pogrep --recursive --ignore-case --blame allogène `
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
|
|
98
pogrep.py
98
pogrep.py
|
@ -1,7 +1,7 @@
|
|||
"""Find translations examples by grepping in .po files.
|
||||
"""
|
||||
|
||||
__version__ = "0.1.2"
|
||||
__version__ = "0.1.4"
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
|
@ -10,6 +10,7 @@ import sys
|
|||
from textwrap import fill
|
||||
from typing import Sequence, NamedTuple, List, Tuple, Optional
|
||||
from shutil import get_terminal_size
|
||||
from subprocess import run, CalledProcessError
|
||||
|
||||
import regex
|
||||
import polib
|
||||
|
@ -136,14 +137,12 @@ def find_in_po(
|
|||
|
||||
def display_results(
|
||||
matches: Sequence[Match],
|
||||
pattern: str,
|
||||
line_number: bool,
|
||||
files_with_matches: bool,
|
||||
args: argparse.Namespace,
|
||||
grep_colors: GrepColors,
|
||||
):
|
||||
"""Display matches as a colorfull table."""
|
||||
files = {match.file for match in matches}
|
||||
if files_with_matches: # Just print filenames
|
||||
if args.files_with_matches: # Just print filenames
|
||||
for file in files:
|
||||
if grep_colors:
|
||||
print(grep_colors.start("fn") + file + grep_colors.NO_COLOR)
|
||||
|
@ -155,9 +154,9 @@ def display_results(
|
|||
term_width = get_terminal_size()[0]
|
||||
for match in matches:
|
||||
left = match.msgid
|
||||
if line_number:
|
||||
if args.line_number:
|
||||
pnum = str(match.line) + ":"
|
||||
if len(files) > 1:
|
||||
if args.print_filenames:
|
||||
pfile = match.file + ":"
|
||||
else:
|
||||
pfile = ""
|
||||
|
@ -172,7 +171,10 @@ def display_results(
|
|||
if grep_colors:
|
||||
print(
|
||||
colorize(
|
||||
tabulate(table, tablefmt="fancy_grid"), pattern, grep_colors, prefixes
|
||||
tabulate(table, tablefmt="fancy_grid"),
|
||||
args.pattern,
|
||||
grep_colors,
|
||||
prefixes,
|
||||
)
|
||||
)
|
||||
else:
|
||||
|
@ -273,6 +275,7 @@ def parse_args() -> argparse.Namespace:
|
|||
)
|
||||
parser.add_argument(
|
||||
"--exclude-dir",
|
||||
action="append",
|
||||
help="Skip any command-line directory with a name suffix that matches "
|
||||
"the pattern. "
|
||||
"When searching recursively, skip any subdirectory whose base name "
|
||||
|
@ -291,18 +294,57 @@ def parse_args() -> argparse.Namespace:
|
|||
"environment variable GREP_COLORS. The deprecated environment variable "
|
||||
"GREP_COLOR is still supported, but its setting does not have priority.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--blame",
|
||||
action="store_true",
|
||||
help="Annotate each line from git information for the entries of each "
|
||||
"match line. Implies --no-source and --translation.",
|
||||
)
|
||||
parser.add_argument("pattern")
|
||||
parser.add_argument("path", nargs="*")
|
||||
return parser.parse_args()
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.color == "auto":
|
||||
args.color = sys.stdout.isatty()
|
||||
else:
|
||||
args.color = args.color != "never"
|
||||
if args.fixed_strings:
|
||||
args.pattern = regex.escape(args.pattern)
|
||||
if args.word_regexp:
|
||||
args.pattern = r"\b" + args.pattern + r"\b"
|
||||
if args.ignore_case:
|
||||
args.pattern = r"(?i)" + args.pattern
|
||||
if args.blame:
|
||||
args.no_source = True
|
||||
args.translation = True
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def run_git(
|
||||
lines_list: Sequence[int], filename: str, pattern: str, grep_colors: GrepColors
|
||||
):
|
||||
"""run git blame for the specified lines in filename
|
||||
|
||||
if grep_colors is not None then the pattern is highlighted
|
||||
"""
|
||||
cmd_line = ["git", "blame"]
|
||||
cmd_line.extend(f"-L {line},/^$/" for line in lines_list)
|
||||
cmd_line.append(filename)
|
||||
try:
|
||||
result = run(cmd_line, capture_output=True, text=True, check=True)
|
||||
except CalledProcessError as exc:
|
||||
print(exc.stderr, file=sys.stderr)
|
||||
return
|
||||
if grep_colors:
|
||||
print(colorize(result.stdout, pattern, grep_colors))
|
||||
else:
|
||||
print(result.stdout)
|
||||
|
||||
|
||||
def main():
|
||||
"""Command line entry point."""
|
||||
args = parse_args()
|
||||
if args.color == "auto":
|
||||
args.color = sys.stdout.isatty()
|
||||
else:
|
||||
args.color = args.color != "never"
|
||||
if args.color:
|
||||
grep_colors = GrepColors()
|
||||
try:
|
||||
|
@ -311,24 +353,34 @@ def main():
|
|||
pass
|
||||
else:
|
||||
grep_colors = None
|
||||
if args.fixed_strings:
|
||||
args.pattern = regex.escape(args.pattern)
|
||||
if args.word_regexp:
|
||||
args.pattern = r"\b" + args.pattern + r"\b"
|
||||
if args.ignore_case:
|
||||
args.pattern = r"(?i)" + args.pattern
|
||||
files = process_path(args.path, args.recursive)
|
||||
args.print_filenames = len(files) > 1
|
||||
if args.exclude_dir:
|
||||
files = [f for f in files if args.exclude_dir.rstrip(os.sep) + os.sep not in f]
|
||||
files = [
|
||||
f
|
||||
for f in files
|
||||
if not any(excl.rstrip(os.sep) + os.sep in f for excl in args.exclude_dir)
|
||||
]
|
||||
errors, results = find_in_po(args.pattern, files, args.no_source, args.translation)
|
||||
if not args.no_messages:
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
if args.blame:
|
||||
current_file = ""
|
||||
lines_list = []
|
||||
for res in results:
|
||||
if res.file != current_file:
|
||||
if current_file:
|
||||
run_git(lines_list, current_file, args.pattern, grep_colors)
|
||||
current_file = res.file
|
||||
lines_list = []
|
||||
lines_list.append(res.line)
|
||||
if lines_list:
|
||||
run_git(lines_list, current_file, args.pattern, grep_colors)
|
||||
return
|
||||
display_results(
|
||||
results,
|
||||
args.pattern,
|
||||
args.line_number,
|
||||
args.files_with_matches,
|
||||
args,
|
||||
grep_colors,
|
||||
)
|
||||
|
||||
|
|
|
@ -1,3 +1,41 @@
|
|||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
requires = ["setuptools>=61.2"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pogrep"
|
||||
description = "Find translations examples by grepping in .po files."
|
||||
authors = [{name = "Julien Palard", email = "julien@palard.fr"}]
|
||||
license = {text = "MIT License"}
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Natural Language :: English",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
]
|
||||
urls = {Homepage = "https://github.com/JulienPalard/pogrep"}
|
||||
requires-python = ">= 3.6"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"polib",
|
||||
"tabulate",
|
||||
]
|
||||
dynamic = ["version"]
|
||||
|
||||
[project.readme]
|
||||
file = "README.md"
|
||||
content-type = "text/markdown; charset=UTF-8"
|
||||
|
||||
[project.scripts]
|
||||
pogrep = "pogrep:main"
|
||||
|
||||
[tool.setuptools]
|
||||
py-modules = ["pogrep"]
|
||||
include-package-data = false
|
||||
|
||||
[tool.setuptools.dynamic.version]
|
||||
attr = "pogrep.__version__"
|
30
setup.cfg
30
setup.cfg
|
@ -1,30 +0,0 @@
|
|||
[metadata]
|
||||
name = pogrep
|
||||
version = 0.1.2
|
||||
description = Find translations examples by grepping in .po files.
|
||||
long_description = file: README.md
|
||||
long_description_content_type = text/markdown; charset=UTF-8
|
||||
author = Julien Palard
|
||||
author_email = julien@palard.fr
|
||||
url = https://github.com/JulienPalard/pogrep
|
||||
license = MIT License
|
||||
classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Intended Audience :: Developers
|
||||
License :: OSI Approved :: MIT License
|
||||
Natural Language :: English
|
||||
Programming Language :: Python :: 3
|
||||
Programming Language :: Python :: 3.6
|
||||
Programming Language :: Python :: 3.7
|
||||
Programming Language :: Python :: 3.8
|
||||
|
||||
[options]
|
||||
py_modules = pogrep
|
||||
python_requires = >= 3.6
|
||||
install_requires =
|
||||
regex
|
||||
polib
|
||||
tabulate
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts = pogrep=pogrep:main
|
Loading…
Reference in New Issue