Spaces:
Runtime error
Runtime error
add code_analyzer and code_fetcher to fetch repo code and analyze imports
Browse files- .gitignore +1 -0
- .pre-commit-config.yaml +13 -13
- Makefile +2 -1
- README.md +4 -0
- app.py +8 -0
- py_code_analyzer/code_analyzer.py +39 -0
- py_code_analyzer/code_fetcher.py +19 -0
- setup.cfg +11 -8
- tests/__init__.py +0 -0
.gitignore
CHANGED
@@ -1 +1,2 @@
|
|
1 |
.DS_Store
|
|
|
|
1 |
.DS_Store
|
2 |
+
.coverage
|
.pre-commit-config.yaml
CHANGED
@@ -31,17 +31,17 @@ repos:
|
|
31 |
types: [python]
|
32 |
pass_filenames: false
|
33 |
|
34 |
-
- id: pytest
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
|
41 |
-
- id: pytest-cov
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
31 |
types: [python]
|
32 |
pass_filenames: false
|
33 |
|
34 |
+
# - id: pytest
|
35 |
+
# name: pytest
|
36 |
+
# stages: [commit]
|
37 |
+
# language: system
|
38 |
+
# entry: pipenv run pytest
|
39 |
+
# types: [python]
|
40 |
|
41 |
+
# - id: pytest-cov
|
42 |
+
# name: pytest
|
43 |
+
# stages: [push]
|
44 |
+
# language: system
|
45 |
+
# entry: pipenv run pytest --cov
|
46 |
+
# types: [python]
|
47 |
+
# pass_filenames: false
|
Makefile
CHANGED
@@ -1,7 +1,8 @@
|
|
1 |
format:
|
2 |
pipenv run black py_code_analyzer && \
|
3 |
pipenv run isort py_code_analyzer && \
|
|
|
4 |
pipenv run mypy
|
5 |
|
6 |
test:
|
7 |
-
pipenv run pytest --cov
|
|
|
1 |
format:
|
2 |
pipenv run black py_code_analyzer && \
|
3 |
pipenv run isort py_code_analyzer && \
|
4 |
+
pipenv run flake8 && \
|
5 |
pipenv run mypy
|
6 |
|
7 |
test:
|
8 |
+
pipenv run pytest --cov
|
README.md
CHANGED
@@ -14,3 +14,7 @@ input to one GitHub public repo's URL(input)
|
|
14 |
## Used technologies
|
15 |
|
16 |
- Streamlit
|
|
|
|
|
|
|
|
|
|
14 |
## Used technologies
|
15 |
|
16 |
- Streamlit
|
17 |
+
|
18 |
+
## References
|
19 |
+
|
20 |
+
- [How to set up a perfect Python project](https://sourcery.ai/blog/python-best-practices/)
|
app.py
CHANGED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from py_code_analyzer.code_analyzer import CodeAnalyzer
|
2 |
+
from py_code_analyzer.code_fetcher import get_repository_python_files
|
3 |
+
|
4 |
+
python_files = get_repository_python_files("cyyeh", "gradio")
|
5 |
+
|
6 |
+
code_analyzer = CodeAnalyzer(python_files)
|
7 |
+
code_analyzer.analyze_imports()
|
8 |
+
code_analyzer.report_imports()
|
py_code_analyzer/code_analyzer.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import ast
|
2 |
+
from pprint import pprint
|
3 |
+
|
4 |
+
import requests
|
5 |
+
|
6 |
+
|
7 |
+
class CodeAnalyzer:
|
8 |
+
class NodeVisitor(ast.NodeVisitor):
|
9 |
+
def __init__(self, imports):
|
10 |
+
self.imports = imports
|
11 |
+
|
12 |
+
def visit_Import(self, node):
|
13 |
+
for alias in node.names:
|
14 |
+
self.imports[-1]["imports"].append(
|
15 |
+
{"module": None, "name": alias.name, "level": -1}
|
16 |
+
)
|
17 |
+
self.generic_visit(node)
|
18 |
+
|
19 |
+
def visit_ImportFrom(self, node):
|
20 |
+
for alias in node.names:
|
21 |
+
self.imports[-1]["imports"].append(
|
22 |
+
{"module": node.module, "name": alias.name, "level": node.level}
|
23 |
+
)
|
24 |
+
self.generic_visit(node)
|
25 |
+
|
26 |
+
def __init__(self, python_files):
|
27 |
+
self.imports = []
|
28 |
+
self.python_files = python_files
|
29 |
+
self._node_visitor = CodeAnalyzer.NodeVisitor(self.imports)
|
30 |
+
|
31 |
+
def analyze_imports(self):
|
32 |
+
for python_file in self.python_files:
|
33 |
+
program = requests.get(python_file["download_url"]).text
|
34 |
+
tree = ast.parse(program)
|
35 |
+
self.imports += [{"file_name": python_file["name"], "imports": []}]
|
36 |
+
self._node_visitor.visit(tree)
|
37 |
+
|
38 |
+
def report_imports(self):
|
39 |
+
pprint(self.imports)
|
py_code_analyzer/code_fetcher.py
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""This file deals with every detail of how to get all python files in the given directory
|
2 |
+
"""
|
3 |
+
import requests
|
4 |
+
|
5 |
+
|
6 |
+
def get_repository_python_files(owner: str, repo: str, path: str = "", ref: str = ""):
|
7 |
+
"""https://docs.github.com/en/rest/repos/contents#get-repository-content"""
|
8 |
+
api_url = f"https://api.github.com/repos/{owner}/{repo}/contents/{path}"
|
9 |
+
if ref:
|
10 |
+
api_url += f"?ref={ref}"
|
11 |
+
|
12 |
+
python_files = []
|
13 |
+
api_results = requests.get(api_url).json()
|
14 |
+
|
15 |
+
for result in api_results:
|
16 |
+
if result["type"] == "file" and result["name"].endswith(".py"):
|
17 |
+
python_files.append(result)
|
18 |
+
|
19 |
+
return python_files
|
setup.cfg
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
[isort]
|
2 |
-
multi_line_output=3
|
3 |
-
include_trailing_comma=True
|
4 |
-
force_grid_wrap=0
|
5 |
-
use_parentheses=True
|
6 |
-
line_length=88
|
7 |
|
8 |
[flake8]
|
9 |
ignore = E203, E266, E501, W503
|
@@ -12,8 +12,11 @@ max-complexity = 18
|
|
12 |
select = B,C,E,F,W,T4
|
13 |
|
14 |
[mypy]
|
15 |
-
files=py_code_analyzer
|
16 |
-
ignore_missing_imports=
|
|
|
|
|
|
|
17 |
|
18 |
[tool:pytest]
|
19 |
-
testpaths=tests
|
|
|
1 |
[isort]
|
2 |
+
multi_line_output = 3
|
3 |
+
include_trailing_comma = True
|
4 |
+
force_grid_wrap = 0
|
5 |
+
use_parentheses = True
|
6 |
+
line_length = 88
|
7 |
|
8 |
[flake8]
|
9 |
ignore = E203, E266, E501, W503
|
|
|
12 |
select = B,C,E,F,W,T4
|
13 |
|
14 |
[mypy]
|
15 |
+
files = py_code_analyzer
|
16 |
+
ignore_missing_imports = True
|
17 |
+
|
18 |
+
[mypy-requests]
|
19 |
+
ignore_missing_imports = True
|
20 |
|
21 |
[tool:pytest]
|
22 |
+
testpaths = tests
|
tests/__init__.py
DELETED
File without changes
|