beautify logged commands issued by koji

Related: https://pagure.io/koji/issue/929
This commit is contained in:
Tomas Kopecek 2022-06-15 13:07:07 +02:00
parent 234cefdf1c
commit 9e741bfb9e
3 changed files with 56 additions and 5 deletions

View file

@ -80,7 +80,7 @@ from koji.tasks import (
ServerExit,
ServerRestart
)
from koji.util import dslice, dslice_ex, isSuccess, parseStatus, to_list
from koji.util import dslice, dslice_ex, isSuccess, parseStatus, to_list, format_shell_cmd
try:
import requests_gssapi as reqgssapi
@ -445,7 +445,7 @@ class BuildRoot(object):
else:
cmd.append('--old-chroot')
cmd.extend(args)
self.logger.info(' '.join(cmd))
self.logger.info(format_shell_cmd(cmd))
workdir = getattr(self, 'workdir', None)
mocklog = 'mock_output.log'
pid = os.fork()
@ -5638,7 +5638,7 @@ class CreaterepoTask(BaseTaskHandler):
status = log_output(self.session, cmd[0], cmd, logfile, self.getUploadDir(), logerror=True)
if not isSuccess(status):
raise koji.GenericError('failed to create repo: %s'
% parseStatus(status, ' '.join(cmd)))
% parseStatus(status, format_shell_cmd(cmd)))
def _get_mergerepo_c_version(self):
cmd = ['/usr/bin/mergerepo_c', '--version']
@ -5737,7 +5737,7 @@ class CreaterepoTask(BaseTaskHandler):
logerror=True, env=env)
if not isSuccess(status):
raise koji.GenericError('failed to merge repos: %s'
% parseStatus(status, ' '.join(cmd)))
% parseStatus(status, format_shell_cmd(cmd)))
class NewDistRepoTask(BaseTaskHandler):
@ -5988,7 +5988,7 @@ class createDistRepoTask(BaseTaskHandler):
status = log_output(self.session, cmd[0], cmd, logfile, self.getUploadDir(), logerror=True)
if not isSuccess(status):
raise koji.GenericError('failed to create repo: %s'
% parseStatus(status, ' '.join(cmd)))
% parseStatus(status, format_shell_cmd(cmd)))
def do_multilib(self, arch, ml_arch, conf):
repodir = koji.pathinfo.distrepo(self.rinfo['id'], self.rinfo['tag_name'])

View file

@ -940,3 +940,28 @@ def to_list(lst):
return lst
else:
return list(lst)
def format_shell_cmd(cmd, text_width=80):
"""
Helper for wrapping shell command lists to human-readable form, while
they still can be copied (from logs) and run in shell.
:param [str] cmd: command list
:returns str:
"""
# account for " \"
text_width -= 2
s = []
line = ''
for bit in cmd:
if len(line + bit) > text_width:
if line:
s.append(line)
line = ''
if line:
line += ' '
line += bit
if line:
s.append(line)
return ' \\\n'.join(s)

View file

@ -3,6 +3,7 @@ from __future__ import absolute_import
import calendar
import errno
import locale
from unittest.case import TestCase
import mock
import optparse
import os
@ -20,6 +21,8 @@ from datetime import datetime
import koji
import koji.util
from koji.util import format_shell_cmd
class EnumTestCase(unittest.TestCase):
@ -1600,5 +1603,28 @@ class TestMoveAndSymlink(unittest.TestCase):
ensuredir.assert_called_once_with('b')
class TestFormatShellCmd(unittest.TestCase):
def test_formats(self):
cases = (
([], ''),
(['random cmd'], 'random cmd'),
(['aa', 'bb'], 'aa bb'),
(['long', 'command', 'with', 'many', 'simple', 'options',
'like', '--option', 'x', '--another-option=x', 'and',
'many', 'more', 'others'],
'long command with many simple options \\\n'
'like --option x --another-option=x and \\\n'
'many more others'),
(['one long line which exceeds the text_width by some amount'],
'one long line which exceeds the text_width by some amount'),
(['one long line which exceeds the text_width by some amount',
'second long line which exceeds the text_width by some amount'],
'one long line which exceeds the text_width by some amount \\\n'
'second long line which exceeds the text_width by some amount'),
)
for inp, out in cases:
self.assertEqual(koji.util.format_shell_cmd(inp, text_width=40), out)
if __name__ == '__main__':
unittest.main()