@click.argument(
'src',
nargs=-1,
- type=click.Path(exists=True, file_okay=True, dir_okay=True, readable=True),
+ type=click.Path(
+ exists=True, file_okay=True, dir_okay=True, readable=True, allow_dash=True
+ ),
)
@click.pass_context
def main(
elif p.is_file():
# if a file was explicitly given, we don't care about its extension
sources.append(p)
+ elif s == '-':
+ sources.append(Path('-'))
else:
err(f'invalid path: {s}')
if len(sources) == 0:
p = sources[0]
report = Report()
try:
- changed = format_file_in_place(
- p, line_length=line_length, fast=fast, write_back=not check
- )
+ if not p.is_file() and str(p) == '-':
+ changed = format_stdin_to_stdout(line_length=line_length, fast=fast)
+ else:
+ changed = format_file_in_place(
+ p, line_length=line_length, fast=fast, write_back=not check
+ )
report.done(p, changed)
except Exception as exc:
report.failed(p, str(exc))
src: Path, line_length: int, fast: bool, write_back: bool = False
) -> bool:
"""Format the file and rewrite if changed. Return True if changed."""
+ with tokenize.open(src) as src_buffer:
+ src_contents = src_buffer.read()
try:
- contents, encoding = format_file(src, line_length=line_length, fast=fast)
+ contents = format_file_contents(
+ src_contents, line_length=line_length, fast=fast
+ )
except NothingChanged:
return False
if write_back:
- with open(src, "w", encoding=encoding) as f:
+ with open(src, "w", encoding=src_buffer.encoding) as f:
f.write(contents)
return True
-def format_file(
- src: Path, line_length: int, fast: bool
-) -> Tuple[FileContent, Encoding]:
+def format_stdin_to_stdout(line_length: int, fast: bool) -> bool:
+ """Format file on stdin and pipe output to stdout. Return True if changed."""
+ contents = sys.stdin.read()
+ try:
+ contents = format_file_contents(contents, line_length=line_length, fast=fast)
+ return True
+
+ except NothingChanged:
+ return False
+
+ finally:
+ sys.stdout.write(contents)
+
+
+def format_file_contents(
+ src_contents: str, line_length: int, fast: bool
+) -> FileContent:
"""Reformats a file and returns its contents and encoding."""
- with tokenize.open(src) as src_buffer:
- src_contents = src_buffer.read()
if src_contents.strip() == '':
- raise NothingChanged(src)
+ raise NothingChanged
dst_contents = format_str(src_contents, line_length=line_length)
if src_contents == dst_contents:
- raise NothingChanged(src)
+ raise NothingChanged
if not fast:
assert_equivalent(src_contents, dst_contents)
assert_stable(src_contents, dst_contents, line_length=line_length)
- return dst_contents, src_buffer.encoding
+ return dst_contents
def format_str(src_contents: str, line_length: int) -> FileContent:
#!/usr/bin/env python3
from functools import partial
+from io import StringIO
from pathlib import Path
+import sys
from typing import Any, List, Tuple
import unittest
from unittest.mock import patch
import black
ll = 88
-ff = partial(black.format_file, line_length=ll, fast=True)
+ff = partial(black.format_file_in_place, line_length=ll, fast=True)
fs = partial(black.format_str, line_length=ll)
THIS_FILE = Path(__file__)
THIS_DIR = THIS_FILE.parent
self.assertFormatEqual(expected, actual)
black.assert_equivalent(source, actual)
black.assert_stable(source, actual, line_length=ll)
- with self.assertRaises(black.NothingChanged):
- ff(THIS_FILE)
+ self.assertFalse(ff(THIS_FILE))
@patch("black.dump_to_file", dump_to_stderr)
def test_black(self) -> None:
self.assertFormatEqual(expected, actual)
black.assert_equivalent(source, actual)
black.assert_stable(source, actual, line_length=ll)
- with self.assertRaises(black.NothingChanged):
- ff(THIS_FILE)
+ self.assertFalse(ff(THIS_DIR / '..' / 'black.py'))
+
+ def test_piping(self) -> None:
+ source, expected = read_data('../black')
+ hold_stdin, hold_stdout = sys.stdin, sys.stdout
+ try:
+ sys.stdin, sys.stdout = StringIO(source), StringIO()
+ sys.stdin.name = '<stdin>'
+ black.format_stdin_to_stdout(line_length=ll, fast=True)
+ sys.stdout.seek(0)
+ actual = sys.stdout.read()
+ finally:
+ sys.stdin, sys.stdout = hold_stdin, hold_stdout
+ self.assertFormatEqual(expected, actual)
+ black.assert_equivalent(source, actual)
+ black.assert_stable(source, actual, line_length=ll)
@patch("black.dump_to_file", dump_to_stderr)
def test_setup(self) -> None:
self.assertFormatEqual(expected, actual)
black.assert_equivalent(source, actual)
black.assert_stable(source, actual, line_length=ll)
- with self.assertRaises(black.NothingChanged):
- ff(THIS_FILE)
+ self.assertFalse(ff(THIS_DIR / '..' / 'setup.py'))
@patch("black.dump_to_file", dump_to_stderr)
def test_function(self) -> None: