add manifest file; cleanup dependencies

This commit is contained in:
Chad Smith 2016-12-21 16:22:29 -08:00 committed by Chad Smith
parent 5dbc937447
commit 2b2cba4351
5 changed files with 57 additions and 49 deletions

View file

@ -1,24 +1,34 @@
[![Build Status](https://travis-ci.org/cs01/gdbgui.svg?branch=master)](https://travis-ci.org/cs01/gdbgui)
Still under active development, with a changing codebase/api.
# A browser-based gui for GDB
The goal of this project is to reduce the learning curve of GDB to zero, including autocompletion and documentation of all commands.
Made with a lightweight Python server (Flask), and JavaScript for the frontend. Simply run the server, then view the page. Tested on Ubuntu 16.04 with Chrome.
## Installation and Use
Either
pip install gdbgui
Or
git clone https://github.com/cs01/gdbgui
pip install -r gdbgui/requirements.txt
gdbgui/gdbgui/backend.py
Then
python -m gdbgui.backend
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Then open `http://127.0.0.1:5000/` in a browser and enjoy!
A pip install package will be released when codebase is more stable
## Compatibility
Tested on Python versions
* 2.7
* 3.3
* 3.4

2
gdbgui/MANIFEST.in Normal file
View file

@ -0,0 +1,2 @@
recursive-include static
recursive-include templates

View file

@ -1,15 +1,18 @@
#!/usr/bin/env python
from flask import Flask, render_template, jsonify, session
from flask import Flask, render_template, jsonify
import os
import argparse
from flask import request
import signal
from ipdb import set_trace as db
from pygdbmi.gdbcontroller import GdbController
import webbrowser
BASE_PATH = os.path.dirname(os.path.realpath(__file__))
TEMPLATE_DIR = os.path.join(BASE_PATH, 'templates')
STATIC_DIR = os.path.join(BASE_PATH, 'static')
DEFAULT_HOST = '0.0.0.0'
DEFAULT_PORT = 5000
app = Flask(__name__, template_folder=TEMPLATE_DIR, static_folder=STATIC_DIR)
@ -17,6 +20,7 @@ app.jinja_env.add_extension('pyjade.ext.jinja.PyJadeExtension')
gdb = None
def server_error(obj):
return jsonify(obj), 500
@ -26,24 +30,24 @@ def client_error(obj):
def get_extra_files():
extra_dirs = ['.']
extra_files = extra_dirs[:]
for extra_dir in extra_dirs:
for dirname, dirs, files in os.walk(extra_dir):
for filename in files:
filename = os.path.join(dirname, filename)
if os.path.isfile(filename):
extra_files.append(filename)
extra_files = []
for dirname, dirs, files in os.walk(TEMPLATE_DIR):
for filename in files:
filename = os.path.join(dirname, filename)
if os.path.isfile(filename):
extra_files.append(filename)
return extra_files
@app.route('/')
def gdbgui():
"""Render the main gdbgui interface"""
return render_template('gdbgui.jade')
@app.route('/run_gdb_command', methods=['POST'])
def run_gdb_command():
"""Run a gdb command"""
if gdb is not None:
try:
cmd = request.form.get('cmd') or request.form.getlist('cmd[]')
@ -54,8 +58,10 @@ def run_gdb_command():
else:
return client_error({'message': 'gdb is not running'})
@app.route('/get_gdb_response')
def get_gdb_response():
"""Return output from gdb.get_gdb_response"""
if gdb is not None:
try:
response = gdb.get_gdb_response()
@ -68,7 +74,7 @@ def get_gdb_response():
@app.route('/read_file')
def read_file():
"""Used to get contents of source files that are being debugged"""
"""Read a file and return its contents as an array"""
path = request.args.get('path')
if path and os.path.isfile(path):
try:
@ -83,8 +89,8 @@ def read_file():
def signal_handler(signal, frame):
"""handle ctrl+c (SIGINT) and make sure the child process is killed!"""
global gdb
"""handle ctrl+c (SIGINT) to make sure the child gdb process is killed"""
print("Received signal %s. Shutting down gdbgui." % signal)
if gdb is not None:
try:
gdb.exit()
@ -96,6 +102,7 @@ def signal_handler(signal, frame):
def quit_backend():
"""Shutdown the flask server. Used when programmitcally testing gdbgui"""
gdb.exit()
func = request.environ.get('werkzeug.server.shutdown')
if func is None:
@ -103,31 +110,39 @@ def quit_backend():
func()
def setup_backend(serve=True, port=5000, debug=False):
def open_browser(host, port):
if host.startswith('http'):
url = '%s:%s' % (host, port)
else:
url = 'http://%s:%s' % (host, port)
print(" * Opening gdbgui in browser (%s)" % url)
webbrowser.open(url)
def setup_backend(serve=True, host=DEFAULT_HOST, port=DEFAULT_PORT, debug=False, view=True):
"""Run the server of the gdb gui"""
global app, gdb
global gdb
signal.signal(signal.SIGINT, signal_handler)
gdb = GdbController()
app.secret_key = 'iusahjpoijeoprkge[0irokmeoprgk890'
app.debug = debug
app.config['TEMPLATES_AUTO_RELOAD'] = True
if serve:
extra_files = []
for dirname, dirs, files in os.walk(TEMPLATE_DIR):
for filename in files:
filename = os.path.join(dirname, filename)
if os.path.isfile(filename):
extra_files.append(filename)
app.run(port=port, extra_files=extra_files)
if view:
open_browser(host, port)
app.run(host=host, port=port, extra_files=get_extra_files())
def main():
"""Entry point from command line"""
parser = argparse.ArgumentParser()
parser.add_argument("--port", default=5000)
parser.add_argument("--port", default=DEFAULT_PORT)
parser.add_argument("--host", default=DEFAULT_HOST)
parser.add_argument("--debug", action='store_true')
parser.add_argument("--view", action='store_true')
args = parser.parse_args()
setup_backend(port=args.port, debug=args.debug)
setup_backend(serve=True, host=args.host, port=args.port, debug=args.debug, view=args.view)
if __name__ == '__main__':

View file

@ -1,23 +1,3 @@
backports.shutil-get-terminal-size==1.0.0
click==6.6
decorator==4.0.10
Flask==0.11.1
ipdb==0.10.1
ipython==5.1.0
ipython-genutils==0.1.0
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
pathlib2==2.1.0
pexpect==4.2.1
pickleshare==0.7.4
prompt-toolkit==1.0.7
ptyprocess==0.5.1
pygdbmi==0.0.1.9
Pygments==2.1.3
pyjade==4.0.0
simplegeneric==0.8.1
six==1.10.0
traitlets==4.2.2
wcwidth==0.1.7
Werkzeug==0.11.11

View file

@ -3,7 +3,7 @@ import sys
# from distutils.core import setup,
EXCLUDE_FROM_PACKAGES = []
version = '0.0.0.3'
version = '0.0.0.4'
class TestCommand (Command):
@ -42,6 +42,7 @@ setup(
install_requires=[
'Flask>=0.11.1',
'pygdbmi>=0.0.1.9',
'pyjade>=4.0.0'
],
classifiers=[
'Intended Audience :: Developers',