mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-17 08:14:42 +04:00
Implement a simplified xargs in python
This commit is contained in:
parent
a5b56bd9e3
commit
b7d395410b
13 changed files with 130 additions and 62 deletions
59
pre_commit/xargs.py
Normal file
59
pre_commit/xargs.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from pre_commit.util import cmd_output
|
||||
|
||||
|
||||
# Limit used previously to avoid "xargs ... Bad file number" on windows
|
||||
# This is slightly less than the posix mandated minimum
|
||||
MAX_LENGTH = 4000
|
||||
|
||||
|
||||
class ArgumentTooLongError(RuntimeError):
|
||||
pass
|
||||
|
||||
|
||||
def partition(cmd, varargs, _max_length=MAX_LENGTH):
|
||||
cmd = tuple(cmd)
|
||||
ret = []
|
||||
|
||||
ret_cmd = []
|
||||
total_len = len(' '.join(cmd))
|
||||
# Reversed so arguments are in order
|
||||
varargs = list(reversed(varargs))
|
||||
|
||||
while varargs:
|
||||
arg = varargs.pop()
|
||||
|
||||
if total_len + 1 + len(arg) <= _max_length:
|
||||
ret_cmd.append(arg)
|
||||
total_len += len(arg)
|
||||
elif not ret_cmd:
|
||||
raise ArgumentTooLongError(arg)
|
||||
else:
|
||||
# We've exceeded the length, yield a command
|
||||
ret.append(cmd + tuple(ret_cmd))
|
||||
ret_cmd = []
|
||||
total_len = len(' '.join(cmd))
|
||||
varargs.append(arg)
|
||||
|
||||
ret.append(cmd + tuple(ret_cmd))
|
||||
|
||||
return tuple(ret)
|
||||
|
||||
|
||||
def xargs(cmd, varargs):
|
||||
"""A simplified implementation of xargs."""
|
||||
retcode = 0
|
||||
stdout = b''
|
||||
stderr = b''
|
||||
|
||||
for run_cmd in partition(cmd, varargs):
|
||||
proc_retcode, proc_out, proc_err = cmd_output(
|
||||
*run_cmd, encoding=None, retcode=None
|
||||
)
|
||||
retcode |= proc_retcode
|
||||
stdout += proc_out
|
||||
stderr += proc_err
|
||||
|
||||
return retcode, stdout, stderr
|
||||
Loading…
Add table
Add a link
Reference in a new issue