Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • nahomy/diffoscope
  • reproducible-builds/diffoscope
  • eighthave/diffoscope
  • justinkb-guest/diffoscope
  • xavierbriand-guest/diffoscope
  • mattia/diffoscope
  • gaviriar-guest/diffoscope
  • amurzeau/diffoscope
  • marmarek/diffoscope
  • wjt/diffoscope
  • mgedmin/diffoscope
  • aparcar-guest/diffoscope
  • chabala/diffoscope
  • jelle/diffoscope
  • ygy/diffoscope
  • grahamc-guest/diffoscope
  • emaste-guest/diffoscope
  • bradfordboyle/diffoscope
  • kerlyn-guest/diffoscope
  • aarushi-guest/diffoscope
  • weatherwaxed-guest/diffoscope
  • vagishagupta23-guest/diffoscope
  • soumya-guest/diffoscope
  • m-boselli-guest/diffoscope
  • Vibhu-guest/diffoscope
  • akanksham-guest/diffoscope
  • JPEWhacker-guest/diffoscope
  • mikeroyal-guest/diffoscope
  • marc-guest/diffoscope
  • lamby/diffoscope
  • pabs/diffoscope
  • sangy-guest/diffoscope
  • dr_rtx/diffoscope
  • danielfullmer/diffoscope
  • FrazerClews/diffoscope
  • xXxrAinZyian/diffoscope
  • jelmer/diffoscope
  • ratschance/diffoscope
  • jimis/diffoscope
  • rclobus-guest/diffoscope
  • jgart/diffoscope
  • zach.welch.timesys/diffoscope
  • SmileyKeith/diffoscope
  • rbalint/diffoscope
  • zbyszek-guest/diffoscope
  • benjaminp/diffoscope
  • JRomain/diffoscope
  • trofi/diffoscope
  • blmaier-col/diffoscope
  • spillner/diffoscope
  • primeos-guest/diffoscope
  • qyliss/diffoscope
  • obfusk/diffoscope
  • cbaines-guest/diffoscope
  • thesamesam/diffoscope
  • AkihiroSuda/diffoscope
  • efraim-guest/diffoscope
  • dkg/diffoscope
  • Raviu/diffoscope
  • tchx84/diffoscope
  • fridtjof/diffoscope
  • felixonmars/diffoscope
  • ernstki/diffoscope
  • sethmlarson/diffoscope
  • Vekhir2/diffoscope
  • amarshall/diffoscope
66 results
Show changes
Commits on Source (6)
......@@ -19,8 +19,13 @@
# You should have received a copy of the GNU General Public License
# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
import sys
import logging
import importlib
import traceback
from ..logging import line_ereser
logger = logging.getLogger(__name__)
......@@ -108,6 +113,7 @@ class ComparatorManager(object):
self.classes = []
for xs in self.COMPARATORS:
errors = []
for x in xs:
package, klass_name = x.rsplit('.', 1)
......@@ -115,16 +121,22 @@ class ComparatorManager(object):
mod = importlib.import_module(
'diffoscope.comparators.{}'.format(package)
)
except ImportError:
except ImportError as e:
errors.append((x, e))
continue
self.classes.append(getattr(mod, klass_name))
break
else: # noqa
raise ImportError("Could not import {}{}".format(
"any of" if len(xs) > 1 else '',
logger.error("Could not import {}{}".format(
"any of " if len(xs) > 1 else '',
', '.join(xs)
))
for x in errors:
logger.error("Original error for %s:", x[0])
sys.stderr.buffer.write(line_ereser())
traceback.print_exception(None, x[1], x[1].__traceback__)
sys.exit(2)
logger.debug("Loaded %d comparator classes", len(self.classes))
......
......@@ -80,6 +80,14 @@ if not hasattr(libarchive.ffi, 'entry_gname'):
'entry_gname', [libarchive.ffi.c_archive_entry_p], ctypes.c_char_p)
libarchive.ArchiveEntry.gname = property(
lambda self: libarchive.ffi.entry_gname(self._entry_p))
# Monkeypatch libarchive-c (>= 2.8)
# Wire mtime_nsec attribute as some libarchive versions (>=2.8) don't expose it
# for ArchiveEntry. Doing this allows a unified API no matter which version is
# available.
if not hasattr(libarchive.ArchiveEntry, 'mtime_nsec') and hasattr(libarchive.ffi, 'entry_mtime_nsec'):
libarchive.ArchiveEntry.mtime_nsec = property(
lambda self: libarchive.ffi.entry_mtime_nsec(self._entry_p))
# Monkeypatch libarchive-c so we always get pathname as (Unicode) str
# Otherwise, we'll get sometimes str and sometimes bytes and always pain.
......
......@@ -17,10 +17,27 @@
# You should have received a copy of the GNU General Public License
# along with diffoscope. If not, see <https://www.gnu.org/licenses/>.
import sys
import contextlib
import logging
def line_ereser(fd=sys.stderr) -> bytes:
ereser = b'' # avoid None to avoid 'NoneType + str/bytes' failures
if fd.isatty():
from curses import tigetstr, setupterm
setupterm(fd=fd.fileno())
ereser = tigetstr('el')
if not ereser and fd.isatty():
# is a tty, but doesn't support the proper scape code, so let's fake it
from shutil import get_terminal_size
width = get_terminal_size().columns
ereser = b'\r{}\r'.format(b' ' * width)
return ereser
@contextlib.contextmanager
def setup_logging(debug, log_handler):
logger = logging.getLogger()
......@@ -32,6 +49,7 @@ def setup_logging(debug, log_handler):
logger.addHandler(ch)
formatter = logging.Formatter(
line_ereser().decode('ascii') +
'%(asctime)s %(levelname).1s: %(name)s: %(message)s',
'%Y-%m-%d %H:%M:%S',
)
......
......@@ -33,7 +33,7 @@ from .path import set_path
from .tools import tool_prepend_prefix, tool_required, OS_NAMES, get_current_os
from .config import Config
from .locale import set_locale
from .logging import setup_logging
from .logging import line_ereser, setup_logging
from .progress import ProgressManager, Progress
from .profiling import ProfileManager, profile
from .tempfiles import clean_all_temp_files
......@@ -459,13 +459,12 @@ def main(args=None):
post_parse(parsed_args)
sys.exit(run_diffoscope(parsed_args))
except KeyboardInterrupt:
if log_handler:
log_handler.progressbar.bar.erase_line()
logger.info('Keyboard Interrupt')
sys.exit(2)
except BrokenPipeError:
sys.exit(2)
except Exception:
sys.stderr.buffer.write(line_ereser())
traceback.print_exc()
if parsed_args and parsed_args.debugger:
import pdb
......
......@@ -24,6 +24,9 @@ import json
import signal
import logging
from .logging import line_ereser
logger = logging.getLogger(__name__)
......@@ -215,12 +218,7 @@ class ProgressBar(object):
kwargs.setdefault('fd', sys.stderr)
super().__init__(*args, **kwargs)
# Terminal handling after parent init since that sets self.fd
if self.fd.isatty():
from curses import tigetstr, setupterm
setupterm()
self.erase_to_eol = tigetstr('el')
else:
self.erase_to_eol = None
self.erase_to_eol = line_ereser(self.fd)
def _need_update(self):
return True
......@@ -228,13 +226,7 @@ class ProgressBar(object):
def erase_line(self):
if self.erase_to_eol:
self.fd.buffer.write(self.erase_to_eol)
elif self.fd.isatty():
print(end='\r', file=self.fd)
print(' ' * self.term_width, end='', file=self.fd)
else:
# Do not flush if nothing was written
return
self.fd.flush()
self.fd.flush()
def finish(self):
self.finished = True
......