Merge "sourcedr: Use relative path to android root dir"
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/functional_tests.py b/vndk/tools/source-deps-reviewer/sourcedr/functional_tests.py
index c97aed8..630ced4 100755
--- a/vndk/tools/source-deps-reviewer/sourcedr/functional_tests.py
+++ b/vndk/tools/source-deps-reviewer/sourcedr/functional_tests.py
@@ -1,32 +1,39 @@
#!/usr/bin/env python3
-from sourcedr.data_utils import *
+from sourcedr.data_utils import data_path, load_data, remove_data
from sourcedr.preprocess import CodeSearch
-from sourcedr.server import *
+from sourcedr.server import app, args
from flask import Flask, jsonify, render_template, request
from flask_testing import LiveServerTestCase, TestCase
from urllib.request import urlopen
+
import flask_testing
+import json
import os
import unittest
app.config['TESTING'] = True
+ANDROID_ROOT = 'sourcedr/test'
+
class TestPreprocess(unittest.TestCase):
def test_prepare(self):
remove_data()
- engine = CodeSearch.create_default(android_root='sourcedr/test')
+ engine = CodeSearch.create_default(android_root=ANDROID_ROOT)
engine.build_index()
engine.find(patterns=['dlopen'], is_regexs=[False])
self.assertTrue(os.path.exists(data_path))
class TestViews(TestCase):
def create_app(self):
+ # TODO: This refers to `sourcedr.server.args`. This should be removed
+ # in the upcoming refactor process.
+ args.android_root = ANDROID_ROOT
return app
def setUp(self):
- engine = CodeSearch.create_default(android_root='sourcedr/test')
+ engine = CodeSearch.create_default(android_root=ANDROID_ROOT)
engine.build_index()
engine.find(patterns=['dlopen'], is_regexs=[False])
@@ -34,15 +41,15 @@
remove_data()
def test_get_file(self):
- test_arg = 'sourcedr/test/example.c'
+ test_arg = 'example.c'
response = self.client.get('/get_file',
query_string=dict(path=test_arg))
ret = response.json['result']
- with open(test_arg, 'r') as f:
+ with open(os.path.join(ANDROID_ROOT, test_arg), 'r') as f:
self.assertEqual(ret, f.read())
def test_load_file(self):
- test_arg = os.path.abspath('sourcedr/test/dlopen/test.c')
+ test_arg = 'dlopen/test.c'
test_arg += ':10: handle = dlopen("libm.so.6", RTLD_LAZY);'
response = self.client.get('/load_file',
query_string=dict(path=test_arg))
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py b/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py
index 9176fec..a859c9e 100755
--- a/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py
+++ b/vndk/tools/source-deps-reviewer/sourcedr/preprocess.py
@@ -170,7 +170,8 @@
return cs
def __init__(self, android_root, index_path):
- self.android_root = android_root
+ android_root = os.path.expanduser(android_root)
+ self.android_root = os.path.abspath(android_root)
self.env = dict(os.environ)
self.env["CSEARCHINDEX"] = os.path.abspath(index_path)
self.filters = {}
@@ -180,7 +181,7 @@
self.filters[ext] = Filter
def build_index(self):
- android_root = os.path.expanduser(self.android_root)
+ android_root = self.android_root
print('building csearchindex for the directory ' + android_root + '...')
subprocess.call(['cindex', android_root], env=self.env)
@@ -195,6 +196,20 @@
pass
return code
+ def remove_prefix(self, raw_grep):
+ ret = b''
+ patt = re.compile(b'([^:]+):(\\d+):(.*)$')
+ for line in raw_grep.split(b'\n'):
+ match = patt.match(line)
+ if not match:
+ continue
+ file_path = os.path.relpath(match.group(1),
+ self.android_root.encode('utf-8'))
+ line_no = match.group(2)
+ code = match.group(3)
+ ret += file_path + b':' + line_no + b':' + code + b'\n'
+ return ret
+
def process_grep(self, raw_grep, pattern, is_regex):
pattern = pattern.encode('utf-8')
if not is_regex:
@@ -225,11 +240,12 @@
if any(patt in file_path for patt in PATH_PATTERN_BLACK_LIST):
continue
+ abs_file_path = os.path.join(self.android_root.encode('utf-8'),
+ file_path)
# Check if any pattern can be found after sanitize_code
- if not pattern.search(self.sanitize_code(file_path)):
+ if not pattern.search(self.sanitize_code(abs_file_path)):
continue
-
- suspect[file_path].append((file_path, line_no, code))
+ suspect[abs_file_path].append((file_path, line_no, code))
suspect = sorted(suspect.items())
@@ -283,13 +299,13 @@
try:
raw_grep = subprocess.check_output(
['csearch', '-n', pattern],
- cwd=os.path.expanduser(self.android_root),
+ cwd=self.android_root,
env=self.env)
except subprocess.CalledProcessError as e:
if e.output == b'':
print('nothing found')
return b''
- return raw_grep
+ return self.remove_prefix(raw_grep)
def raw_search(self, pattern, is_regex):
if not is_regex:
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/server.py b/vndk/tools/source-deps-reviewer/sourcedr/server.py
index be4e323..fdccf8a 100755
--- a/vndk/tools/source-deps-reviewer/sourcedr/server.py
+++ b/vndk/tools/source-deps-reviewer/sourcedr/server.py
@@ -20,22 +20,27 @@
if sys.version_info < (3,):
input = raw_input
+# XXX: Global variable to workaround args.android_root in test cases. This
+# should be removed in the upcoming refactoring process.
+args = argparse.Namespace()
+
app = Flask(__name__)
# whether the code segment is exactly in file
def same(fl, code):
+ fl = os.path.join(args.android_root, fl)
with open(fl, 'r') as f:
fc = f.read()
return code in fc
# check if the file needes to be reiewed again
def check(codes):
+ ret = []
for item in codes:
fl = item.split(':')[0]
code = item[len(fl) + 1:]
- if not same(fl, code):
- return False
- return True
+ ret.append(same(fl, code))
+ return ret
@app.route('/get_started')
def _get_started():
@@ -43,7 +48,7 @@
for key, item in sorted(data.items()):
lst.append(key)
if item[0]:
- done.append(check(item[1]))
+ done.append(all(check(item[1])))
else:
done.append(False)
@@ -64,11 +69,14 @@
return jsonify(result='')
deps, codes = data[path]
- return jsonify(deps=json.dumps(deps), codes=json.dumps(codes))
+ return jsonify(deps=json.dumps(deps), codes=json.dumps(codes),
+ okays=json.dumps(check(codes)))
@app.route('/get_file')
def _get_file():
path = request.args.get('path')
+ path = os.path.join(args.android_root, path)
+
if not os.path.exists(path):
return jsonify(result='No such file')
with open(path, 'r') as f:
@@ -98,7 +106,6 @@
save_new_pattern(patt, is_regex)
return jsonify(result='done')
-
# This function does a temporary grep to the directory
# Not adding the result to database
@app.route('/temporary_search')
@@ -174,6 +181,7 @@
# a CodeSearch engine must be initialized with the
# root of the directory and the path of the csearch index file
engine = CodeSearch.create_default(args.android_root, args.index_path)
+ args.android_root = os.path.expanduser(args.android_root)
print('Be careful that previous data files will merge with new data files.')
print('Delete previous data files(data.json, patterns) if you want ' +
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js b/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js
index db62041..e805705 100644
--- a/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js
+++ b/vndk/tools/source-deps-reviewer/sourcedr/static/js/main.js
@@ -5,6 +5,33 @@
var counter = 0;
var current_item = null;
+ // make item list sortable
+ $( function() {
+ $("#item_list").sortable();
+ $("#item_list").disableSelection();
+ });
+
+ function moveToTop(index) {
+ if (index == 0) {
+ return;
+ }
+ let target = $('#item_list').children().eq(index);
+ let tp = $('#item_list').children().eq(0);
+ let old_offset = target.position();
+ tp.before(target);
+ let new_offset = target.position();
+ let tmp = target.clone().appendTo('#item_list')
+ .css('position', 'absolute')
+ .css('left', old_offset.left)
+ .css('top', old_offset.top);
+ target.hide();
+ let new_pos = {'top': new_offset.top, 'left': new_offset.left};
+ tmp.animate(new_pos, 'slow', function() {
+ target.show();
+ tmp.remove();
+ });
+ }
+
function getSelText() {
let txt = window.getSelection();
$('#selected_text').val(txt);
@@ -18,8 +45,9 @@
'<input type="submit" class="delete" value="X">' +'</li>';
}
- function codeHtml(text, cnt) {
- return '<li><span id="code' + cnt + '">' + text +
+ function codeHtml(text, cnt, okay) {
+ return (okay? '<li>' : '<li style="color:red;">') +
+ '<span id="code' + cnt + '">' + text +
'</span><input type="submit" class="delete" value="X">' + '</li>';
}
@@ -90,7 +118,7 @@
function enterCode() {
let text = $('#code_file_path').val() + ':' + $('#selected_text').val();
- $('#code_list').append(codeHtml(text, ccounter));
+ $('#code_list').append(codeHtml(text, ccounter, true));
$('.delete').click(function () {
$(this).parent().remove();
});
@@ -98,13 +126,13 @@
return false;
}
- function setCode(codes) {
+ function setCode(codes, okays) {
$('#code_list').empty();
ccounter = 0;
let len = codes.length;
for (let i = 0; i < len; i++) {
let text = codes[i];
- $('#code_list').append(codeHtml(text, ccounter));
+ $('#code_list').append(codeHtml(text, ccounter, okays[i]));
$('.delete').click(function () {
$(this).parent().remove();
});
@@ -165,6 +193,23 @@
deps: JSON.stringify(deps),
codes: JSON.stringify(codes)
});
+ let target = $(current_item).text().split(':')[2];
+ let children = $('#item_list')[0].children;
+ let len = children.length;
+ for (let i = 0; i < len; i++) {
+ let tt = children[i].getElementsByTagName('a')[0].innerHTML;
+ if (tt == $(current_item).text()) {
+ continue;
+ }
+ if (children[i].getElementsByTagName('a')[0].className ==
+ 'list-group-item list-group-item-success' ) {
+ continue;
+ }
+ let content = tt.split(':')[2];
+ if (content == target) {
+ moveToTop(i);
+ }
+ }
return false;
}
@@ -189,6 +234,8 @@
function unsetHighlightLine() {
$('#browsing_file').removeAttr('data-line');
+ // Add this line to ensure that all highlight divs are removed
+ $('.line-highlight').remove();
}
function removeAnchor() {
@@ -216,8 +263,9 @@
}, function (data) {
let deps = JSON.parse(data.deps);
let codes = JSON.parse(data.codes);
+ let okays = JSON.parse(data.okays);
setTask(deps);
- setCode(codes);
+ setCode(codes, okays);
});
setBrowsingFile(file);
@@ -237,8 +285,7 @@
$inputs.each(function () {
values[this.name] = $(this).val();
});
- let path = $('#path_prefix').text() +
- $('input[name="browsing_path"]').val();
+ let path = $('input[name="browsing_path"]').val();
setBrowsingFile(path);
unsetHighlightLine();
return false;
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html b/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html
index 9cf75ec..f03ced3 100644
--- a/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html
+++ b/vndk/tools/source-deps-reviewer/sourcedr/templates/index.html
@@ -9,13 +9,15 @@
<link rel="stylesheet" href="static/css/main.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+ <!-- Added for sortable list -->
+ <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<div class="container-fluid">
<div class="row content">
<h2 style="padding-left:20px;">Code review tool</h2>
- <div id="item_list" class="col-sm-3 sidenav hidden-xs"></div>
+ <ol id="item_list" class="col-sm-3"></ol>
<div class="col-sm-5">
<h3>Browsing:</h3>
diff --git a/vndk/tools/source-deps-reviewer/sourcedr/test/example.c b/vndk/tools/source-deps-reviewer/sourcedr/test/example.c
index 4648f14..f8e329f 100644
--- a/vndk/tools/source-deps-reviewer/sourcedr/test/example.c
+++ b/vndk/tools/source-deps-reviewer/sourcedr/test/example.c
@@ -1,9 +1,10 @@
int main() {
- printf("This is a simple testing filen");
+ printf("This is a simple testing file\n");
int dlopen_analysis = 1;
"This line with dlopen shouldn't be found"
/*
* This dlopen shouldn't be found
*/
dlopen("dlopen");
+ handle = dlopen("libm.so.6", RTLD_LAZY);
}