-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 83fdbc0
Showing
14 changed files
with
437 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
version: 2.1 | ||
|
||
orbs: | ||
codacy: codacy/[email protected] | ||
codacy_plugins_test: codacy/[email protected] | ||
|
||
jobs: | ||
test_patterns: | ||
machine: | ||
image: ubuntu-1604:201903-01 | ||
working_directory: ~/workdir | ||
steps: | ||
- attach_workspace: | ||
at: ~/ | ||
- run: | ||
command: | | ||
docker build -t $CIRCLE_PROJECT_REPONAME:latest . | ||
docker run $CIRCLE_PROJECT_REPONAME:latest codacy_prospector_test.py | ||
docker save --output ~/workdir/docker-image.tar $CIRCLE_PROJECT_REPONAME:latest | ||
- persist_to_workspace: | ||
paths: | ||
- workdir/* | ||
root: ~/ | ||
workflows: | ||
version: 2 | ||
compile_test_deploy: | ||
jobs: | ||
- codacy/checkout_and_version | ||
- test_patterns: | ||
requires: | ||
- codacy/checkout_and_version | ||
- codacy_plugins_test/run: | ||
name: plugins_test | ||
requires: | ||
- test_patterns | ||
- codacy/shell: | ||
name: publish_dockerhub | ||
context: CodacyDocker | ||
cmd: | | ||
docker load --input ~/workdir/docker-image.tar | ||
docker login -u $DOCKER_USER -p $DOCKER_PASS | ||
docker tag $CIRCLE_PROJECT_REPONAME codacy/$CIRCLE_PROJECT_REPONAME:$(cat .version) | ||
docker tag $CIRCLE_PROJECT_REPONAME codacy/$CIRCLE_PROJECT_REPONAME:latest | ||
docker push codacy/$CIRCLE_PROJECT_REPONAME:$(cat .version) | ||
docker push codacy/$CIRCLE_PROJECT_REPONAME:latest | ||
requires: | ||
- plugins_test | ||
filters: | ||
branches: | ||
only: | ||
- master | ||
- codacy/tag_version: | ||
name: tag_version | ||
context: CodacyAWS | ||
requires: | ||
- publish_dockerhub |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
* @lolgab @ljmf00 @andreaTP @rtfpessoa @bmbferreira @DReigada @pedrocodacy | ||
|
||
*.yml @h314to @paulopontesm | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/RUNNING_PID | ||
/logs/ | ||
/project/*-shim.sbt | ||
/project/project | ||
target | ||
.idea | ||
.DS_Store | ||
.metals | ||
.bloop | ||
.vscode | ||
__pycache__ | ||
.mypy_cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
version = "2.0.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
FROM python:3.7-slim | ||
COPY requirements.txt requirements.txt | ||
RUN pip3 install --no-cache-dir -r requirements.txt | ||
COPY src/codacy_prospector.py codacy_prospector.py | ||
COPY src/codacy_prospector_test.py codacy_prospector_test.py | ||
COPY docs /docs | ||
RUN useradd -u 2004 -U docker | ||
RUN mkdir /home/docker | ||
RUN chown -R docker:docker /docs /home/docker | ||
USER docker | ||
ENTRYPOINT [ "python3.7" ] | ||
CMD [ "codacy_prospector.py" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
Copyright 2015 Codacy. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
[](https://www.codacy.com/app/Codacy/codacy-prospector) | ||
[](https://circleci.com/gh/codacy/codacy-prospector) | ||
|
||
# Codacy Prospector | ||
|
||
This is the docker engine we use at Codacy to have [Prospector](https://github.com/PyCQA/prospector) support. | ||
You can also create a docker to integrate the tool and language of your choice! | ||
See the [codacy-engine-scala-seed](https://github.com/codacy/codacy-engine-scala-seed) repository for more information. | ||
|
||
## Usage | ||
|
||
You can create the docker by doing: | ||
|
||
```bash | ||
docker build -t codacy-prospector:latest . | ||
``` | ||
|
||
The docker is ran with the following command: | ||
|
||
```bash | ||
docker run -it -v $srcDir:/src codacy-prospector:latest | ||
``` | ||
|
||
## Generate Docs | ||
|
||
1. Update the version in `docs/patterns.json` | ||
2. Run the DocGenerator: | ||
|
||
```bash | ||
sbt "doc-generator/run" | ||
``` | ||
|
||
## Test | ||
|
||
We use the [codacy-plugins-test](https://github.com/codacy/codacy-plugins-test) to test our external tools integration. | ||
You can follow the instructions there to make sure your tool is working as expected. | ||
|
||
## What is Codacy? | ||
|
||
[Codacy](https://www.codacy.com/) is an Automated Code Review Tool that monitors your technical debt, helps you improve your code quality, teaches best practices to your developers, and helps you save time in Code Reviews. | ||
|
||
### Among Codacy’s features | ||
|
||
- Identify new Static Analysis issues | ||
- Commit and Pull Request Analysis with GitHub, BitBucket/Stash, GitLab (and also direct git repositories) | ||
- Auto-comments on Commits and Pull Requests | ||
- Integrations with Slack, HipChat, Jira, YouTrack | ||
- Track issues in Code Style, Security, Error Proneness, Performance, Unused Code and other categories | ||
|
||
Codacy also helps keep track of Code Coverage, Code Duplication, and Code Complexity. | ||
|
||
Codacy supports PHP, Python, Ruby, Java, JavaScript, and Scala, among others. | ||
|
||
### Free for Open Source | ||
|
||
Codacy is free for Open Source projects. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"name": "Prospector", | ||
"version": "1.1.7", | ||
"patterns": [ | ||
{ | ||
"patternId": "pylint_unused-variable", | ||
"level": "Error", | ||
"category": "CodeStyle" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
##Patterns: pylint_unused-variable | ||
import json | ||
def readJsonFile(path): | ||
##Err: pylint_unused-variable | ||
a = 1 | ||
with open(path, 'r') as file: | ||
res = json.loads(file.read()) | ||
return res |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Prospector is a tool to analyse Python code and output information about errors, potential problems, convention violations and complexity. | ||
|
||
It brings together the functionality of other Python analysis tools such as [Pylint](https://pylint.readthedocs.io/), [pep8](https://pep8.readthedocs.io/), and [McCabe complexity](https://pypi.python.org/pypi/mccabe). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
mypy==0.720 | ||
prospector[with_everything]==1.1.7 | ||
jsonpickle==1.2 | ||
Django==2.2.5 | ||
Flask==1.1.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import os | ||
import sys | ||
import json | ||
import jsonpickle | ||
from subprocess import Popen, PIPE | ||
import ast | ||
import glob | ||
import re | ||
import signal | ||
from contextlib import contextmanager | ||
|
||
@contextmanager | ||
def timeout(time): | ||
# Register a function to raise a TimeoutError on the signal. | ||
signal.signal(signal.SIGALRM, lambda: sys.exit(2)) | ||
# Schedule the signal to be sent after ``time``. | ||
signal.alarm(time) | ||
yield | ||
|
||
DEFAULT_TIMEOUT = 16 * 60 | ||
def getTimeout(timeoutString): | ||
l = timeoutString.split() | ||
if len(l) != 2 or not l[0].isdigit(): | ||
return DEFAULT_TIMEOUT | ||
elif l[1] == "second" or l[1] == "seconds": | ||
return int(l[0]) | ||
elif l[1] == "minute" or l[1] == "minutes": | ||
return int(l[0]) * 60 | ||
elif l[1] == "hour" or l[1] == "hours": | ||
return int(l[0]) * 60 * 60 | ||
else: | ||
return DEFAULT_TIMEOUT | ||
|
||
class Result: | ||
def __init__(self, filename, message, patternId, line): | ||
self.filename = filename | ||
self.message = message | ||
self.patternId = patternId | ||
self.line = line | ||
def __str__(self): | ||
return f'Result({self.filename},{self.message},{self.patternId},{self.line})' | ||
def __repr__(self): | ||
return self.__str__() | ||
def __eq__(self, o): | ||
return self.filename == o.filename and self.message == o.message and self.patternId == o.patternId and self.line == o.line | ||
|
||
def toJson(obj): return jsonpickle.encode(obj, unpicklable=False) | ||
|
||
def readJsonFile(path): | ||
with open(path, 'r') as file: | ||
res = json.loads(file.read()) | ||
return res | ||
|
||
def runProspector(options, files, cwd=None): | ||
process = Popen( | ||
['python3', '-m', 'prospector', ] + options + files, | ||
stdout=PIPE, | ||
cwd=cwd | ||
) | ||
stdout = process.communicate()[0] | ||
return stdout.decode('utf-8') | ||
|
||
def isPython3(f): | ||
try: | ||
with open(f, 'r') as stream: | ||
try: | ||
ast.parse(stream.read()) | ||
except (ValueError, TypeError, UnicodeError): | ||
# Assume it's the current interpreter. | ||
return True | ||
except SyntaxError: | ||
# the other version or an actual syntax error on current interpreter | ||
return False | ||
else: | ||
return True | ||
except Exception: | ||
# Shouldn't happen, but if it does, just assume there's | ||
# something inherently wrong with the file. | ||
return True | ||
|
||
def parseResult(json_text): | ||
messages = json.loads(json_text)["messages"] | ||
def createResults(): | ||
for res in messages: | ||
location = res['location'] | ||
yield Result(filename=location['path'], message=res['message'], patternId=f"{res['source']}_{res['code']}", line=location['line']) | ||
return list(createResults()) | ||
|
||
def walkDirectory(directory): | ||
def generate(): | ||
for filename in glob.iglob(os.path.join(directory, '**/*.py'), recursive=True): | ||
res = os.path.relpath(filename, directory) | ||
yield res | ||
return list(generate()) | ||
|
||
def readConfiguration(configFile, srcDir): | ||
def allFiles(): return walkDirectory(srcDir) | ||
try: | ||
configuration = readJsonFile(configFile) | ||
files = configuration.get('files') or allFiles() | ||
except Exception: | ||
files = allFiles() | ||
return [f for f in files if isPython3(f)] | ||
|
||
def chunks(lst,n): | ||
return [lst[i:i + n] for i in range(0, len(lst), n)] | ||
|
||
def runProspectorWith(files, cwd): | ||
res = runProspector([ | ||
'--output-format=json', | ||
'--with-tool=frosted', | ||
'--with-tool=vulture', | ||
'--with-tool=pyroma', | ||
'--with-tool=mypy'], | ||
files, | ||
cwd) | ||
return parseResult(res) | ||
|
||
def runTool(configFile, srcDir): | ||
files = readConfiguration(configFile, srcDir) | ||
res = [] | ||
filesWithPath = [os.path.join(srcDir,f) for f in files] | ||
for chunk in chunks(filesWithPath, 10): | ||
res.extend(runProspectorWith(chunk, srcDir)) | ||
for result in res: | ||
if result.filename.startswith(srcDir): | ||
result.filename = os.path.relpath(result.filename, srcDir) | ||
return res | ||
|
||
def resultsToJson(results): | ||
return os.linesep.join([toJson(res) for res in results]) | ||
|
||
if __name__ == '__main__': | ||
with timeout(getTimeout(os.environ.get('TIMEOUT') or '')): | ||
try: | ||
results = runTool('/.codacyrc', '/src') | ||
print(resultsToJson(results)) | ||
except Exception: | ||
traceback.print_exc() | ||
sys.exit(1) |
Oops, something went wrong.