Skip to content

Commit

Permalink
Merge pull request #1832 from bitwiseman/task/common_shell
Browse files Browse the repository at this point in the history
Refactor python cssbeautifier to reuse jsbeautifier CLI methods
  • Loading branch information
bitwiseman authored Aug 20, 2020
2 parents d763fe1 + 90b6e55 commit 4ffd339
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 243 deletions.
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,18 @@ js/lib/*.js: $(BUILD_DIR)/node $(BUILD_DIR)/generate $(wildcard js/src/*) $(wild
# python package generation
python/dist/*: $(BUILD_DIR)/python $(wildcard python/**/*.py) python/jsbeautifier/* python/cssbeautifier/*
@echo Building python package...
rm -f python/dist/*
@rm -f python/dist/*
@cd python && \
cp setup-js.py setup.py && \
cp setup-css.py setup.py && \
$(PYTHON) setup.py sdist && \
rm setup.py
@cd python && \
cp setup-css.py setup.py && \
cp setup-js.py setup.py && \
$(PYTHON) setup.py sdist && \
rm setup.py
$(SCRIPT_DIR)/python-rel pip install -U python/dist/*
# Order matters here! Install css then js to make sure the local dist version of js is used
$(SCRIPT_DIR)/python-rel pip install -U python/dist/cssbeautifier*
$(SCRIPT_DIR)/python-rel pip install -U python/dist/jsbeautifier*

# python package generation
build/*.tgz: js/lib/*.js
Expand Down Expand Up @@ -129,6 +131,9 @@ $(BUILD_DIR)/node: package.json package-lock.json | $(BUILD_DIR)

$(BUILD_DIR)/python: python/setup-js.py python/setup-css.py | $(BUILD_DIR) $(BUILD_DIR)/virtualenv
@$(PYTHON) --version
# Order matters here! Install css then js to make sure the local dist version of js is used
@cp ./python/setup-css.py ./python/setup.py
$(SCRIPT_DIR)/python-dev pip install -e ./python
@cp ./python/setup-js.py ./python/setup.py
$(SCRIPT_DIR)/python-dev pip install -e ./python
@rm ./python/setup.py
Expand Down
87 changes: 33 additions & 54 deletions python/cssbeautifier/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
import copy
import getopt
from cssbeautifier.__version__ import __version__
from jsbeautifier import isFileDifferent, mkdir_p
from jsbeautifier.cli import *
from cssbeautifier.css.options import BeautifierOptions
from cssbeautifier.css.beautifier import Beautifier

Expand All @@ -48,22 +48,7 @@ def beautify(string, opts=None):


def beautify_file(file_name, opts=None):
if file_name == "-": # stdin
try:
if sys.stdin.isatty():
raise Exception()

stream = sys.stdin
except Exception:
print("Must pipe input or define input file.\n", file=sys.stderr)
usage(sys.stderr)
raise Exception()
else:
stream = open(file_name)

content = "".join(stream.readlines())
b = Beautifier(content, opts)
return b.beautify()
return process_file(file_name, opts, beautify)


def usage(stream=sys.stdout):
Expand Down Expand Up @@ -125,6 +110,7 @@ def main():
argv,
"hvio:rs:c:e:tnb:",
[
"editorconfig",
"help",
"usage",
"version",
Expand All @@ -150,11 +136,11 @@ def main():

css_options = default_options()

file = None
outfile = "stdout"
filepath_params = []
filepath_params.extend(args)

outfile_param = "stdout"
replace = False
if len(args) == 1:
file = args[0]

for opt, arg in opts:
if opt in ("--stdin", "-i"):
Expand Down Expand Up @@ -190,41 +176,34 @@ def main():
css_options.space_around_combinator = True
elif opt in ("--indent-empty-lines"):
css_options.indent_empty_lines = True

if not file:
file = "-"
elif opt in ("--editorconfig"):
css_options.editorconfig = True

try:
if outfile == "stdout" and replace and not file == "-":
outfile = file

pretty = beautify_file(file, css_options)

if outfile == "stdout":
# python automatically converts newlines in text to "\r\n" when on windows
# switch to binary to prevent this
if sys.platform == "win32":
import msvcrt

msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

sys.stdout.write(pretty)
else:
if isFileDifferent(outfile, pretty):
mkdir_p(os.path.dirname(outfile))

# python automatically converts newlines in text to "\r\n" when on windows
# set newline to empty to prevent this
with io.open(outfile, "wt", newline="") as f:
print("writing " + outfile, file=sys.stderr)
try:
f.write(pretty)
except TypeError:
# This is not pretty, but given how we did the version import
# it is the only way to do this without having setup.py
# fail on a missing six dependency.
six = __import__("six")
f.write(six.u(pretty))
filepaths, replace = get_filepaths_from_params(filepath_params, replace)
for filepath in filepaths:
if not replace:
outfile = outfile_param
else:
outfile = filepath

css_options = integrate_editorconfig_options(
filepath, css_options, outfile, "js"
)

pretty = beautify_file(filepath, css_options)

write_beautified_output(pretty, css_options, outfile)

except MissingInputStreamError:
print("Must pipe input or define at least one file.\n", file=sys.stderr)
usage(sys.stderr)
return 1

except UnicodeError as ex:
print("Error while decoding input or encoding output:", file=sys.stderr)
print(ex, file=sys.stderr)
return 1

except Exception as ex:
print(ex, file=sys.stderr)
Expand Down
196 changes: 14 additions & 182 deletions python/jsbeautifier/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import copy
import glob
from jsbeautifier.__version__ import __version__
from jsbeautifier.cli import *
from jsbeautifier.javascript.options import BeautifierOptions
from jsbeautifier.javascript.beautifier import Beautifier

Expand Down Expand Up @@ -63,9 +64,13 @@
#
# Here are the available options: (read source)


class MissingInputStreamError(Exception):
pass
__all__ = [
"default_options",
"beautify",
"beautify_file",
"usage",
"main",
]


def default_options():
Expand All @@ -77,75 +82,8 @@ def beautify(string, opts=default_options()):
return b.beautify(string, opts)


def set_file_editorconfig_opts(filename, js_options):
from editorconfig import get_properties, EditorConfigError

try:
_ecoptions = get_properties(os.path.abspath(filename))

if _ecoptions.get("indent_style") == "tab":
js_options.indent_with_tabs = True
elif _ecoptions.get("indent_style") == "space":
js_options.indent_with_tabs = False

if _ecoptions.get("indent_size"):
js_options.indent_size = int(_ecoptions["indent_size"])

if _ecoptions.get("max_line_length"):
if _ecoptions.get("max_line_length") == "off":
js_options.wrap_line_length = 0
else:
js_options.wrap_line_length = int(_ecoptions["max_line_length"])

if _ecoptions.get("insert_final_newline") == "true":
js_options.end_with_newline = True
elif _ecoptions.get("insert_final_newline") == "false":
js_options.end_with_newline = False

if _ecoptions.get("end_of_line"):
if _ecoptions["end_of_line"] == "cr":
js_options.eol = "\r"
elif _ecoptions["end_of_line"] == "lf":
js_options.eol = "\n"
elif _ecoptions["end_of_line"] == "crlf":
js_options.eol = "\r\n"

except EditorConfigError:
# do not error on bad editor config
print("Error loading EditorConfig. Ignoring.", file=sys.stderr)


def beautify_file(file_name, opts=default_options()):
input_string = ""
if file_name == "-": # stdin
if sys.stdin.isatty():
raise MissingInputStreamError()

stream = sys.stdin
if platform.platform().lower().startswith("windows"):
if sys.version_info.major >= 3:
# for python 3 on windows this prevents conversion
stream = io.TextIOWrapper(sys.stdin.buffer, newline="")
elif platform.architecture()[0] == "32bit":
# for python 2 x86 on windows this prevents conversion
import msvcrt

msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
else:
raise Exception(
"Pipe to stdin not supported on Windows with Python 2.x 64-bit."
)

input_string = stream.read()

# if you pipe an empty string, that is a failure
if input_string == "":
raise MissingInputStreamError()
else:
stream = io.open(file_name, "rt", newline="", encoding="UTF-8")
input_string = stream.read()

return beautify(input_string, opts)
return process_file(file_name, opts, beautify)


def usage(stream=sys.stdout):
Expand Down Expand Up @@ -217,24 +155,6 @@ def usage(stream=sys.stdout):
return 0


def mkdir_p(path):
try:
if path:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST and os.path.isdir(path):
pass
else:
raise Exception()


def isFileDifferent(filepath, expected):
try:
return "".join(io.open(filepath, "rt", newline="").readlines()) != expected
except BaseException:
return True


def main():

argv = sys.argv[1:]
Expand Down Expand Up @@ -357,108 +277,20 @@ def main():
return usage()

try:
filepaths = []
if not filepath_params or (
len(filepath_params) == 1 and filepath_params[0] == "-"
):
# default to stdin
filepath_params = []
filepaths.append("-")

for filepath_param in filepath_params:
# ignore stdin setting if files are specified
if "-" == filepath_param:
continue

# Check if each literal filepath exists
if os.path.isfile(filepath_param):
filepaths.append(filepath_param)
elif "*" in filepath_param or "?" in filepath_param:
# handle globs
# empty result is okay
if sys.version_info.major == 2 or (
sys.version_info.major == 3 and sys.version_info.minor <= 4
):
if "**" in filepath_param:
raise Exception(
"Recursive globs not supported on Python <= 3.4."
)
filepaths.extend(glob.glob(filepath_param))
else:
filepaths.extend(glob.glob(filepath_param, recursive=True))
else:
# not a glob and not a file
raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), filepath_param)

if len(filepaths) > 1:
replace = True
elif filepaths and filepaths[0] == "-":
replace = False

# remove duplicates
filepaths = set(filepaths)

filepaths, replace = get_filepaths_from_params(filepath_params, replace)
for filepath in filepaths:
if not replace:
outfile = outfile_param
else:
outfile = filepath

# Editorconfig used only on files, not stdin
if getattr(js_options, "editorconfig"):
editorconfig_filepath = filepath

if editorconfig_filepath == "-":
if outfile != "stdout":
editorconfig_filepath = outfile
else:
fileType = "js"
editorconfig_filepath = "stdin." + fileType

# debug("EditorConfig is enabled for ", editorconfig_filepath);
js_options = copy.copy(js_options)
set_file_editorconfig_opts(editorconfig_filepath, js_options)
js_options = integrate_editorconfig_options(
filepath, js_options, outfile, "js"
)

pretty = beautify_file(filepath, js_options)

if outfile == "stdout":
stream = sys.stdout

# python automatically converts newlines in text to "\r\n" when on windows
# switch to binary to prevent this
if platform.platform().lower().startswith("windows"):
if sys.version_info.major >= 3:
# for python 3 on windows this prevents conversion
stream = io.TextIOWrapper(sys.stdout.buffer, newline="")
elif platform.architecture()[0] == "32bit":
# for python 2 x86 on windows this prevents conversion
import msvcrt

msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
else:
raise Exception(
"Pipe to stdout not supported on Windows with Python 2.x 64-bit."
)

stream.write(pretty)
else:
if isFileDifferent(outfile, pretty):
mkdir_p(os.path.dirname(outfile))

# python automatically converts newlines in text to "\r\n" when on windows
# set newline to empty to prevent this
with io.open(outfile, "wt", newline="", encoding="UTF-8") as f:
print("beautified " + outfile, file=sys.stdout)
try:
f.write(pretty)
except TypeError:
# This is not pretty, but given how we did the version import
# it is the only way to do this without having setup.py
# fail on a missing six dependency.
six = __import__("six")
f.write(six.u(pretty))
elif not js_options.keep_quiet:
print("beautified " + outfile + " - unchanged", file=sys.stdout)
write_beautified_output(pretty, js_options, outfile)

except MissingInputStreamError:
print("Must pipe input or define at least one file.\n", file=sys.stderr)
Expand Down
Loading

0 comments on commit 4ffd339

Please sign in to comment.