2013-04-23 18:51:17 +02:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2013-03-27 20:56:56 +01:00
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import select
|
|
|
|
|
|
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
|
|
|
2013-07-29 23:03:31 +02:00
|
|
|
from zerver.lib.unminify import SourceMap
|
2013-03-27 20:56:56 +01:00
|
|
|
|
|
|
|
# Wait for the user to paste text, then time out quickly and
|
|
|
|
# return it. Disable echo so that we can re-echo the same
|
|
|
|
# lines with our annotations.
|
|
|
|
def get_full_paste():
|
|
|
|
try:
|
|
|
|
os.system('stty -echo raw isig')
|
|
|
|
|
|
|
|
data = ''
|
|
|
|
while True:
|
|
|
|
fd = sys.stdin.fileno()
|
|
|
|
can_read = select.select([fd], [], [], 0.1)[0]
|
|
|
|
if can_read:
|
|
|
|
data += os.read(fd, 1)
|
|
|
|
else:
|
|
|
|
if data:
|
|
|
|
return data
|
|
|
|
finally:
|
|
|
|
os.system('stty cooked echo')
|
|
|
|
|
|
|
|
class Command(BaseCommand):
|
2013-07-12 22:01:31 +02:00
|
|
|
args = '<source map directory>'
|
2013-03-27 20:56:56 +01:00
|
|
|
help = '''Add source locations to a stack backtrace generated by minified code.
|
|
|
|
|
|
|
|
The currently checked out code should match the version that generated the error.'''
|
|
|
|
|
|
|
|
def handle(self, *args, **options):
|
|
|
|
if len(args) != 1:
|
2013-07-12 22:01:31 +02:00
|
|
|
raise CommandError('No source map directory specified')
|
2013-03-27 20:56:56 +01:00
|
|
|
|
2013-03-28 18:48:37 +01:00
|
|
|
source_map = SourceMap(args[0])
|
2013-03-27 20:56:56 +01:00
|
|
|
|
|
|
|
if os.isatty(sys.stdin.fileno()):
|
2013-03-28 18:48:37 +01:00
|
|
|
sys.stdout.write('Paste stacktrace:\n\n')
|
2013-03-27 20:56:56 +01:00
|
|
|
sys.stdout.flush()
|
2013-03-28 18:48:37 +01:00
|
|
|
stacktrace = get_full_paste()
|
2013-03-27 20:56:56 +01:00
|
|
|
else:
|
2013-03-28 18:48:37 +01:00
|
|
|
stacktrace = sys.stdin.read()
|
2013-03-27 20:56:56 +01:00
|
|
|
|
2013-03-28 18:48:37 +01:00
|
|
|
sys.stdout.write(source_map.annotate_stacktrace(stacktrace))
|