code-annotations 2.2.0__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {code_annotations-2.2.0 → code_annotations-2.3.0}/MANIFEST.in +1 -1
- {code_annotations-2.2.0 → code_annotations-2.3.0}/PKG-INFO +7 -33
- {code_annotations-2.2.0 → code_annotations-2.3.0}/README.rst +0 -28
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/__init__.py +1 -1
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/base.py +14 -4
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/cli.py +6 -1
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/generate_docs.py +20 -10
- code_annotations-2.3.0/code_annotations/report_templates/html/annotation.tpl +14 -0
- code_annotations-2.3.0/code_annotations/report_templates/html/annotation_data.tpl +8 -0
- code_annotations-2.3.0/code_annotations/report_templates/html/annotation_list.tpl +27 -0
- code_annotations-2.3.0/code_annotations/report_templates/html/base.tpl +92 -0
- code_annotations-2.3.0/code_annotations/report_templates/rst/annotation.tpl +13 -0
- code_annotations-2.3.0/code_annotations/report_templates/rst/annotation_data.tpl +8 -0
- code_annotations-2.3.0/code_annotations/report_templates/rst/annotation_group.tpl +2 -0
- code_annotations-2.3.0/code_annotations/report_templates/rst/annotation_list.tpl +34 -0
- code_annotations-2.3.0/code_annotations/report_templates/rst/base.tpl +41 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/PKG-INFO +7 -33
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/SOURCES.txt +9 -0
- code_annotations-2.3.0/setup.py +111 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_generate_docs.py +35 -1
- code_annotations-2.2.0/setup.py +0 -110
- {code_annotations-2.2.0 → code_annotations-2.3.0}/CHANGELOG.rst +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/LICENSE.txt +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/NOTICE.txt +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/annotation_errors.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/config/__init__.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/config/feature_toggle_annotations.yaml +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/config/openedx_events_annotations.yaml +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/config/setting_annotations.yaml +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/sphinx/extensions/__init__.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/sphinx/extensions/base.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/sphinx/extensions/featuretoggles.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/sphinx/extensions/openedx_events.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/sphinx/extensions/settings.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/exceptions.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/extensions/__init__.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/extensions/base.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/extensions/javascript.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/extensions/python.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/find_django.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/find_static.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/helpers.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/dependency_links.txt +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/entry_points.txt +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/not-zip-safe +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/requires.txt +3 -3
- {code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/top_level.txt +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/requirements/base.in +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/setup.cfg +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_base.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_django_coverage.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_django_generate_safelist.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_django_list_local_models.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_find_django.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_find_static.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_search.py +0 -0
- {code_annotations-2.2.0 → code_annotations-2.3.0}/tests/test_sphinx.py +0 -0
|
@@ -4,4 +4,4 @@ include CONTRIBUTING.rst
|
|
|
4
4
|
include LICENSE.txt
|
|
5
5
|
include README.rst
|
|
6
6
|
include requirements/base.in
|
|
7
|
-
recursive-include code_annotations *.html *.png *.gif *js *.css *jpg *jpeg *svg *py *.yaml *.yml
|
|
7
|
+
recursive-include code_annotations *.tpl *.html *.png *.gif *js *.css *jpg *jpeg *svg *py *.yaml *.yml
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: code-annotations
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Extensible tools for parsing annotations in codebases
|
|
5
5
|
Home-page: https://github.com/openedx/code-annotations
|
|
6
6
|
Author: edX
|
|
@@ -10,6 +10,7 @@ Keywords: edx pii code annotations
|
|
|
10
10
|
Classifier: Development Status :: 3 - Alpha
|
|
11
11
|
Classifier: Framework :: Django
|
|
12
12
|
Classifier: Framework :: Django :: 4.2
|
|
13
|
+
Classifier: Framework :: Django :: 5.2
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
14
15
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
16
|
Classifier: Natural Language :: English
|
|
@@ -21,11 +22,11 @@ Requires-Python: >=3.11
|
|
|
21
22
|
Description-Content-Type: text/x-rst
|
|
22
23
|
License-File: LICENSE.txt
|
|
23
24
|
License-File: NOTICE.txt
|
|
24
|
-
Requires-Dist:
|
|
25
|
+
Requires-Dist: python-slugify
|
|
26
|
+
Requires-Dist: stevedore
|
|
25
27
|
Requires-Dist: click
|
|
28
|
+
Requires-Dist: pyyaml
|
|
26
29
|
Requires-Dist: Jinja2
|
|
27
|
-
Requires-Dist: stevedore
|
|
28
|
-
Requires-Dist: python-slugify
|
|
29
30
|
Provides-Extra: django
|
|
30
31
|
Requires-Dist: Django>=4.2; extra == "django"
|
|
31
32
|
Dynamic: author
|
|
@@ -36,6 +37,7 @@ Dynamic: description-content-type
|
|
|
36
37
|
Dynamic: home-page
|
|
37
38
|
Dynamic: keywords
|
|
38
39
|
Dynamic: license
|
|
40
|
+
Dynamic: license-file
|
|
39
41
|
Dynamic: provides-extra
|
|
40
42
|
Dynamic: requires-dist
|
|
41
43
|
Dynamic: requires-python
|
|
@@ -44,9 +46,6 @@ Dynamic: summary
|
|
|
44
46
|
code-annotations
|
|
45
47
|
=============================
|
|
46
48
|
|
|
47
|
-
|pypi-badge| |CI| |codecov-badge| |doc-badge| |pyversions-badge|
|
|
48
|
-
|license-badge|
|
|
49
|
-
|
|
50
49
|
Extensible tools for parsing annotations in codebases
|
|
51
50
|
|
|
52
51
|
Overview
|
|
@@ -100,31 +99,6 @@ refer to this `list of resources`_ if you need any assistance.
|
|
|
100
99
|
.. _list of resources: https://open.edx.org/getting-help
|
|
101
100
|
|
|
102
101
|
|
|
103
|
-
.. |pypi-badge| image:: https://img.shields.io/pypi/v/code-annotations.svg
|
|
104
|
-
:target: https://pypi.python.org/pypi/code-annotations/
|
|
105
|
-
:alt: PyPI
|
|
106
|
-
|
|
107
|
-
.. |CI| image:: https://github.com/openedx/code-annotations/workflows/Python%20CI/badge.svg?branch=master
|
|
108
|
-
:target: https://github.com/openedx/code-annotations/actions?query=workflow%3A%22Python+CI%22
|
|
109
|
-
:alt: CI
|
|
110
|
-
|
|
111
|
-
.. |codecov-badge| image:: http://codecov.io/github/edx/code-annotations/coverage.svg?branch=master
|
|
112
|
-
:target: http://codecov.io/github/edx/code-annotations?branch=master
|
|
113
|
-
:alt: Codecov
|
|
114
|
-
|
|
115
|
-
.. |doc-badge| image:: https://readthedocs.org/projects/code-annotations/badge/?version=latest
|
|
116
|
-
:target: http://code-annotations.readthedocs.io/en/latest/
|
|
117
|
-
:alt: Documentation
|
|
118
|
-
|
|
119
|
-
.. |pyversions-badge| image:: https://img.shields.io/pypi/pyversions/code-annotations.svg
|
|
120
|
-
:target: https://pypi.python.org/pypi/code-annotations/
|
|
121
|
-
:alt: Supported Python versions
|
|
122
|
-
|
|
123
|
-
.. |license-badge| image:: https://img.shields.io/github/license/edx/code-annotations.svg
|
|
124
|
-
:target: https://github.com/openedx/code-annotations/blob/master/LICENSE.txt
|
|
125
|
-
:alt: License
|
|
126
|
-
|
|
127
|
-
|
|
128
102
|
Change Log
|
|
129
103
|
----------
|
|
130
104
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
code-annotations
|
|
2
2
|
=============================
|
|
3
3
|
|
|
4
|
-
|pypi-badge| |CI| |codecov-badge| |doc-badge| |pyversions-badge|
|
|
5
|
-
|license-badge|
|
|
6
|
-
|
|
7
4
|
Extensible tools for parsing annotations in codebases
|
|
8
5
|
|
|
9
6
|
Overview
|
|
@@ -55,28 +52,3 @@ Have a question about this repository, or about Open edX in general? Please
|
|
|
55
52
|
refer to this `list of resources`_ if you need any assistance.
|
|
56
53
|
|
|
57
54
|
.. _list of resources: https://open.edx.org/getting-help
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
.. |pypi-badge| image:: https://img.shields.io/pypi/v/code-annotations.svg
|
|
61
|
-
:target: https://pypi.python.org/pypi/code-annotations/
|
|
62
|
-
:alt: PyPI
|
|
63
|
-
|
|
64
|
-
.. |CI| image:: https://github.com/openedx/code-annotations/workflows/Python%20CI/badge.svg?branch=master
|
|
65
|
-
:target: https://github.com/openedx/code-annotations/actions?query=workflow%3A%22Python+CI%22
|
|
66
|
-
:alt: CI
|
|
67
|
-
|
|
68
|
-
.. |codecov-badge| image:: http://codecov.io/github/edx/code-annotations/coverage.svg?branch=master
|
|
69
|
-
:target: http://codecov.io/github/edx/code-annotations?branch=master
|
|
70
|
-
:alt: Codecov
|
|
71
|
-
|
|
72
|
-
.. |doc-badge| image:: https://readthedocs.org/projects/code-annotations/badge/?version=latest
|
|
73
|
-
:target: http://code-annotations.readthedocs.io/en/latest/
|
|
74
|
-
:alt: Documentation
|
|
75
|
-
|
|
76
|
-
.. |pyversions-badge| image:: https://img.shields.io/pypi/pyversions/code-annotations.svg
|
|
77
|
-
:target: https://pypi.python.org/pypi/code-annotations/
|
|
78
|
-
:alt: Supported Python versions
|
|
79
|
-
|
|
80
|
-
.. |license-badge| image:: https://img.shields.io/github/license/edx/code-annotations.svg
|
|
81
|
-
:target: https://github.com/openedx/code-annotations/blob/master/LICENSE.txt
|
|
82
|
-
:alt: License
|
|
@@ -14,6 +14,9 @@ from code_annotations import annotation_errors
|
|
|
14
14
|
from code_annotations.exceptions import ConfigurationException
|
|
15
15
|
from code_annotations.helpers import VerboseEcho
|
|
16
16
|
|
|
17
|
+
PACKAGE_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
18
|
+
DEFAULT_TEMPLATE_DIR = os.path.join(PACKAGE_DIR, "report_templates")
|
|
19
|
+
|
|
17
20
|
|
|
18
21
|
class AnnotationConfig:
|
|
19
22
|
"""
|
|
@@ -58,10 +61,17 @@ class AnnotationConfig:
|
|
|
58
61
|
self.echo(f"Configured for source path: {self.source_path}")
|
|
59
62
|
|
|
60
63
|
self._configure_coverage(raw_config.get('coverage_target', None))
|
|
61
|
-
|
|
62
|
-
self.
|
|
63
|
-
self.
|
|
64
|
-
|
|
64
|
+
|
|
65
|
+
self.rendered_report_format = raw_config.get('rendered_report_format', 'rst')
|
|
66
|
+
self.report_template_dir = raw_config.get(
|
|
67
|
+
'report_template_dir',
|
|
68
|
+
os.path.join(DEFAULT_TEMPLATE_DIR, self.rendered_report_format)
|
|
69
|
+
)
|
|
70
|
+
self.rendered_report_dir = raw_config.get('rendered_report_dir', 'annotation_reports')
|
|
71
|
+
self.rendered_report_source_link_prefix = raw_config.get('rendered_report_source_link_prefix', None)
|
|
72
|
+
self.trim_filename_prefixes = raw_config.get('trim_filename_prefixes', [])
|
|
73
|
+
self.third_party_package_location = raw_config.get('third_party_package_location', "site-packages")
|
|
74
|
+
self.rendered_report_file_extension = f".{self.rendered_report_format}"
|
|
65
75
|
|
|
66
76
|
self._configure_annotations(raw_config)
|
|
67
77
|
self._configure_extensions()
|
|
@@ -241,10 +241,15 @@ def generate_docs(config_file, verbosity, report_files):
|
|
|
241
241
|
try:
|
|
242
242
|
config = AnnotationConfig(config_file, verbosity)
|
|
243
243
|
|
|
244
|
+
if not report_files:
|
|
245
|
+
raise ConfigurationException(
|
|
246
|
+
"No report files provided. Please provide one or more report files to generate docs from."
|
|
247
|
+
)
|
|
248
|
+
|
|
244
249
|
for key in (
|
|
245
250
|
"report_template_dir",
|
|
246
251
|
"rendered_report_dir",
|
|
247
|
-
"
|
|
252
|
+
"rendered_report_format",
|
|
248
253
|
"rendered_report_source_link_prefix",
|
|
249
254
|
):
|
|
250
255
|
if not getattr(config, key):
|
|
@@ -27,8 +27,7 @@ class ReportRenderer:
|
|
|
27
27
|
self.config = config
|
|
28
28
|
self.echo = self.config.echo
|
|
29
29
|
self.report_files = report_files
|
|
30
|
-
self.create_time = datetime.datetime.
|
|
31
|
-
|
|
30
|
+
self.create_time = datetime.datetime.now(tz=datetime.timezone.utc)
|
|
32
31
|
self.full_report = self._aggregate_reports()
|
|
33
32
|
|
|
34
33
|
self.jinja_environment = jinja2.Environment(
|
|
@@ -62,6 +61,12 @@ class ReportRenderer:
|
|
|
62
61
|
loaded_report = yaml.safe_load(report_file)
|
|
63
62
|
|
|
64
63
|
for filename in loaded_report:
|
|
64
|
+
trimmed_filename = filename
|
|
65
|
+
for prefix in self.config.trim_filename_prefixes:
|
|
66
|
+
if filename.startswith(prefix):
|
|
67
|
+
trimmed_filename = filename[len(prefix):]
|
|
68
|
+
break
|
|
69
|
+
|
|
65
70
|
if filename in report:
|
|
66
71
|
for loaded_annotation in loaded_report[filename]:
|
|
67
72
|
found = False
|
|
@@ -74,9 +79,9 @@ class ReportRenderer:
|
|
|
74
79
|
break
|
|
75
80
|
|
|
76
81
|
if not found:
|
|
77
|
-
report[
|
|
82
|
+
report[trimmed_filename].append(loaded_annotation)
|
|
78
83
|
else:
|
|
79
|
-
report[
|
|
84
|
+
report[trimmed_filename] = loaded_report[filename]
|
|
80
85
|
|
|
81
86
|
def _aggregate_reports(self):
|
|
82
87
|
"""
|
|
@@ -91,11 +96,12 @@ class ReportRenderer:
|
|
|
91
96
|
|
|
92
97
|
return report
|
|
93
98
|
|
|
94
|
-
def _write_doc_file(self, doc_filename, doc_data):
|
|
99
|
+
def _write_doc_file(self, doc_title, doc_filename, doc_data):
|
|
95
100
|
"""
|
|
96
101
|
Write out a single report file with the given data. This is rendered using the configured top level template.
|
|
97
102
|
|
|
98
103
|
Args:
|
|
104
|
+
doc_title: Title to use for the document.
|
|
99
105
|
doc_filename: Filename to write to.
|
|
100
106
|
doc_data: Dict of reporting data to use, in the {'file name': [list, of, annotations,]} style.
|
|
101
107
|
"""
|
|
@@ -110,14 +116,16 @@ class ReportRenderer:
|
|
|
110
116
|
|
|
111
117
|
with open(full_doc_filename, 'w') as output:
|
|
112
118
|
output.write(self.top_level_template.render(
|
|
119
|
+
doc_title=doc_title,
|
|
113
120
|
create_time=self.create_time,
|
|
114
121
|
report=doc_data,
|
|
115
122
|
all_choices=self.all_choices,
|
|
116
123
|
all_annotations=self.config.annotation_tokens,
|
|
117
124
|
group_mapping=self.group_mapping,
|
|
118
125
|
slugify=slugify,
|
|
119
|
-
source_link_prefix=self.config.rendered_report_source_link_prefix
|
|
120
|
-
|
|
126
|
+
source_link_prefix=self.config.rendered_report_source_link_prefix,
|
|
127
|
+
third_party_package_location=self.config.third_party_package_location,
|
|
128
|
+
))
|
|
121
129
|
|
|
122
130
|
def _generate_per_choice_docs(self):
|
|
123
131
|
"""
|
|
@@ -130,7 +138,7 @@ class ReportRenderer:
|
|
|
130
138
|
if isinstance(annotation['annotation_data'], list) and choice in annotation['annotation_data']:
|
|
131
139
|
choice_report[filename].append(annotation)
|
|
132
140
|
|
|
133
|
-
self._write_doc_file(f'choice_{choice}', choice_report)
|
|
141
|
+
self._write_doc_file(f"All References to Choice '{choice}'", f'choice_{choice}', choice_report)
|
|
134
142
|
|
|
135
143
|
def _generate_per_annotation_docs(self):
|
|
136
144
|
"""
|
|
@@ -143,13 +151,15 @@ class ReportRenderer:
|
|
|
143
151
|
if report_annotation['annotation_token'] == annotation:
|
|
144
152
|
annotation_report[filename].append(report_annotation)
|
|
145
153
|
|
|
146
|
-
self._write_doc_file(
|
|
154
|
+
self._write_doc_file(
|
|
155
|
+
f"All References to Annotation '{annotation}'", f'annotation_{annotation}', annotation_report
|
|
156
|
+
)
|
|
147
157
|
|
|
148
158
|
def render(self):
|
|
149
159
|
"""
|
|
150
160
|
Perform the rendering of all documentation using the configured Jinja2 templates.
|
|
151
161
|
"""
|
|
152
162
|
# Generate the top level list of all annotations
|
|
153
|
-
self._write_doc_file('index', self.full_report)
|
|
163
|
+
self._write_doc_file("Complete Annotation List", 'index', self.full_report)
|
|
154
164
|
self._generate_per_choice_docs()
|
|
155
165
|
self._generate_per_annotation_docs()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{% if is_third_party %}
|
|
2
|
+
{# no links for third party code since we don't know where to link to #}
|
|
3
|
+
{% if annotation.extra and annotation.extra.object_id %}
|
|
4
|
+
{{ annotation.extra.object_id }} {% if annotation.line_number > 0 %}line {{ annotation.line_number }}{% endif %}: {{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
5
|
+
{% else %}
|
|
6
|
+
{% if loop.changed(annotation.line_number)%}{{ filename }}:{{ annotation.line_number }}<br />{% endif %}:
|
|
7
|
+
{{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
8
|
+
{% endif %}
|
|
9
|
+
|
|
10
|
+
{% elif annotation.extra and annotation.extra.object_id %}
|
|
11
|
+
<a href="{{ source_link_prefix }}{{ filename }}#L{{ annotation.line_number }}" target="_blank">{{ annotation.extra.object_id }} {% if annotation.line_number > 0 %}line {{ annotation.line_number }}{% endif %}</a>: {{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
12
|
+
{% else %}
|
|
13
|
+
<a href="{{ source_link_prefix }}{{ filename }}#L{{ annotation.line_number }}" target="_blank">`{{ filename }}:{{ annotation.line_number }}: {{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
14
|
+
{% endif %}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{% if annotation.annotation_data is sequence and annotation.annotation_data is not string %}
|
|
2
|
+
{% for a in annotation.annotation_data %}
|
|
3
|
+
<a href="choice-{{ slugify(a) }}.html">{{ a }}</a>{% if not loop.last %}, {% endif %}
|
|
4
|
+
{% endfor %}
|
|
5
|
+
|
|
6
|
+
{% else %}
|
|
7
|
+
{{ annotation.annotation_data }}
|
|
8
|
+
{% endif %}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{% extends "base.tpl" %}
|
|
2
|
+
{% block content %}
|
|
3
|
+
Annotations found in {{ report|length }} files.
|
|
4
|
+
|
|
5
|
+
{% for filename in report %}
|
|
6
|
+
{% set is_third_party = third_party_package_location in filename %}
|
|
7
|
+
|
|
8
|
+
<h2 id="file-{{ slugify(filename) }}">{{ filename }}</h2>
|
|
9
|
+
<div class="file-annotations">
|
|
10
|
+
{{ report[filename]|length }} annotations {% if is_third_party %}(installed package){% endif %}<br />
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
{% for annotation in report[filename] %}
|
|
14
|
+
{% if loop.changed(annotation.report_group_id) %}
|
|
15
|
+
{% if not loop.first %}</ul></div>{% endif %}
|
|
16
|
+
<div class="group-annotations"><ul>
|
|
17
|
+
{% endif %}
|
|
18
|
+
<li>{% include 'annotation.tpl' %}</li>
|
|
19
|
+
{% if loop.last %}
|
|
20
|
+
</ul></div>
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% endfor %}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
{% endfor %}
|
|
26
|
+
|
|
27
|
+
{% endblock %}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>{{ doc_title }}</title>
|
|
4
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
5
|
+
<style>
|
|
6
|
+
body {
|
|
7
|
+
font-family: 'Trebuchet MS', sans-serif;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.title {
|
|
11
|
+
text-align: center;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.table {
|
|
15
|
+
display: table;
|
|
16
|
+
border-spacing: 12px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.row {
|
|
20
|
+
display: table-row;
|
|
21
|
+
margin-bottom: 0;
|
|
22
|
+
margin-top: 0;
|
|
23
|
+
width: 100%;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.cell1 {
|
|
27
|
+
display: table-cell;
|
|
28
|
+
width: 20%;
|
|
29
|
+
margin-right: 1%;
|
|
30
|
+
border: 1px solid #ccc;
|
|
31
|
+
margin 12px;
|
|
32
|
+
background-color: #ffffee;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.cell2 {
|
|
36
|
+
display: table-cell;
|
|
37
|
+
width: 79%;
|
|
38
|
+
margin-right: 1%;
|
|
39
|
+
margin 12px;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.group-annotations {
|
|
43
|
+
border: 1px solid #ccc;
|
|
44
|
+
margin: 10px;
|
|
45
|
+
}
|
|
46
|
+
</style>
|
|
47
|
+
</head>
|
|
48
|
+
<body>
|
|
49
|
+
<h1 class="title">{{ doc_title }}</h1>
|
|
50
|
+
|
|
51
|
+
<div class="table">
|
|
52
|
+
<div class="row">
|
|
53
|
+
<div class="cell1">
|
|
54
|
+
<h3><a href="index.html">Home</a></h3>
|
|
55
|
+
|
|
56
|
+
<h3>Annotations</h3>
|
|
57
|
+
|
|
58
|
+
<ul>
|
|
59
|
+
{% for a in all_annotations %}
|
|
60
|
+
<li><a href="annotation-{{ slugify(a) }}.html">annotation_{{ slugify(a) }}</a></li>
|
|
61
|
+
{% endfor %}
|
|
62
|
+
</ul>
|
|
63
|
+
|
|
64
|
+
<h3>Choices</h3>
|
|
65
|
+
|
|
66
|
+
<ul>
|
|
67
|
+
{% for choice in all_choices %}
|
|
68
|
+
<li><a href="choice-{{ slugify(choice) }}.html">choice_{{ slugify(choice) }}</a></li>
|
|
69
|
+
{% endfor %}
|
|
70
|
+
</ul>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="cell2">
|
|
73
|
+
<h2>Files in this page</h2>
|
|
74
|
+
<ul>
|
|
75
|
+
{% for filename in report %}
|
|
76
|
+
<li><a href="#file-{{ slugify(filename) }}">{{ filename }}</a></li>
|
|
77
|
+
{% endfor %}
|
|
78
|
+
</ul>
|
|
79
|
+
|
|
80
|
+
{% block content %}{% endblock %}
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
{% block footer %}
|
|
85
|
+
<div class="footer">
|
|
86
|
+
<br /><br />
|
|
87
|
+
<hr />
|
|
88
|
+
Built at {{ create_time.strftime('%Y-%m-%d %H:%M:%S %Z') }}
|
|
89
|
+
</div>
|
|
90
|
+
{% endblock %}
|
|
91
|
+
</body>
|
|
92
|
+
</html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{% if is_third_party %}
|
|
2
|
+
{# no links for third party code since we don't know where to link to #}
|
|
3
|
+
{% if annotation.extra and annotation.extra.object_id %}
|
|
4
|
+
{{ annotation.extra.object_id }} {% if annotation.line_number > 0 %}line {{ annotation.line_number }}{% endif %}: {{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
5
|
+
{% else %}
|
|
6
|
+
{{ filename }}:{{ annotation.line_number }}: {{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
7
|
+
{% endif %}
|
|
8
|
+
|
|
9
|
+
{% elif annotation.extra and annotation.extra.object_id %}
|
|
10
|
+
`{{ annotation.extra.object_id }} {% if annotation.line_number > 0 %}line {{ annotation.line_number }}{% endif %} <{{ source_link_prefix }}{{ filename }}#L{{ annotation.line_number }}>`_: {{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
11
|
+
{% else %}
|
|
12
|
+
`{{ filename }}:{{ annotation.line_number }} <{{ source_link_prefix }}{{ filename }}#L{{ annotation.line_number }}>`_: {{ annotation.annotation_token }} {% include "annotation_data.tpl" %}
|
|
13
|
+
{% endif %}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{% if annotation.annotation_data is sequence and annotation.annotation_data is not string %}
|
|
2
|
+
{% for a in annotation.annotation_data %}
|
|
3
|
+
choice_{{ slugify(a) }}_{% if not loop.last %}, {% endif %}
|
|
4
|
+
{% endfor %}
|
|
5
|
+
|
|
6
|
+
{% else %}
|
|
7
|
+
{{ annotation.annotation_data }}
|
|
8
|
+
{% endif %}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{% extends "base.tpl" %}
|
|
2
|
+
{% block content %}
|
|
3
|
+
Annotations found in {{ report|length }} files.
|
|
4
|
+
|
|
5
|
+
{% for filename in report %}
|
|
6
|
+
{% set is_third_party = third_party_package_location in filename %}
|
|
7
|
+
|
|
8
|
+
{{ filename }}
|
|
9
|
+
{{ "-" * filename|length }}
|
|
10
|
+
|
|
11
|
+
.. note:: {{ report[filename]|length }} annotations {% if is_third_party %}(installed package){% endif %}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
{% for annotation in report[filename] %}
|
|
15
|
+
{% if annotation.report_group_id %}
|
|
16
|
+
{% if loop.changed(annotation.report_group_id) %}
|
|
17
|
+
{% include 'annotation_group.tpl' %}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
{% endif %}
|
|
21
|
+
* {% include 'annotation.tpl' %}
|
|
22
|
+
|
|
23
|
+
{% else %}
|
|
24
|
+
{% if loop.changed(annotation.report_group_id) %}
|
|
25
|
+
|
|
26
|
+
{% endif %}
|
|
27
|
+
* {% include 'annotation.tpl' %}
|
|
28
|
+
|
|
29
|
+
{% endif %}
|
|
30
|
+
{% endfor %}
|
|
31
|
+
|
|
32
|
+
{% endfor %}
|
|
33
|
+
|
|
34
|
+
{% endblock %}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{{ "#" * doc_title|length }}
|
|
2
|
+
{{ doc_title }}
|
|
3
|
+
{{ "#" * doc_title|length }}
|
|
4
|
+
|
|
5
|
+
.. sidebar:: Table of Contents
|
|
6
|
+
|
|
7
|
+
`Home <index.rst>`_
|
|
8
|
+
|
|
9
|
+
Annotations
|
|
10
|
+
|
|
11
|
+
{% for a in all_annotations %}
|
|
12
|
+
* annotation_{{ slugify(a) }}_
|
|
13
|
+
{% endfor %}
|
|
14
|
+
|
|
15
|
+
Choices
|
|
16
|
+
|
|
17
|
+
{% for choice in all_choices %}
|
|
18
|
+
* choice_{{ slugify(choice) }}_
|
|
19
|
+
{% endfor %}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
.. contents::
|
|
23
|
+
|
|
24
|
+
{% block content %}{% endblock %}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
{# backlinks for all choices #}
|
|
28
|
+
{% for choice in all_choices %}
|
|
29
|
+
.. _choice_{{ slugify(choice) }}: {{ slugify('choice_' + choice) + '.rst' }}
|
|
30
|
+
{% endfor %}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
{# backlinks for all annotations #}
|
|
34
|
+
{% for annotation in all_annotations %}
|
|
35
|
+
.. _annotation_{{ slugify(annotation) }}: {{ slugify('annotation_' + annotation) + '.rst' }}
|
|
36
|
+
{% endfor %}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
{% block footer %}
|
|
40
|
+
Built at {{ create_time.strftime('%Y-%m-%d %H:%M:%S %Z') }}
|
|
41
|
+
{% endblock %}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: code-annotations
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Extensible tools for parsing annotations in codebases
|
|
5
5
|
Home-page: https://github.com/openedx/code-annotations
|
|
6
6
|
Author: edX
|
|
@@ -10,6 +10,7 @@ Keywords: edx pii code annotations
|
|
|
10
10
|
Classifier: Development Status :: 3 - Alpha
|
|
11
11
|
Classifier: Framework :: Django
|
|
12
12
|
Classifier: Framework :: Django :: 4.2
|
|
13
|
+
Classifier: Framework :: Django :: 5.2
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
14
15
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
16
|
Classifier: Natural Language :: English
|
|
@@ -21,11 +22,11 @@ Requires-Python: >=3.11
|
|
|
21
22
|
Description-Content-Type: text/x-rst
|
|
22
23
|
License-File: LICENSE.txt
|
|
23
24
|
License-File: NOTICE.txt
|
|
24
|
-
Requires-Dist:
|
|
25
|
+
Requires-Dist: python-slugify
|
|
26
|
+
Requires-Dist: stevedore
|
|
25
27
|
Requires-Dist: click
|
|
28
|
+
Requires-Dist: pyyaml
|
|
26
29
|
Requires-Dist: Jinja2
|
|
27
|
-
Requires-Dist: stevedore
|
|
28
|
-
Requires-Dist: python-slugify
|
|
29
30
|
Provides-Extra: django
|
|
30
31
|
Requires-Dist: Django>=4.2; extra == "django"
|
|
31
32
|
Dynamic: author
|
|
@@ -36,6 +37,7 @@ Dynamic: description-content-type
|
|
|
36
37
|
Dynamic: home-page
|
|
37
38
|
Dynamic: keywords
|
|
38
39
|
Dynamic: license
|
|
40
|
+
Dynamic: license-file
|
|
39
41
|
Dynamic: provides-extra
|
|
40
42
|
Dynamic: requires-dist
|
|
41
43
|
Dynamic: requires-python
|
|
@@ -44,9 +46,6 @@ Dynamic: summary
|
|
|
44
46
|
code-annotations
|
|
45
47
|
=============================
|
|
46
48
|
|
|
47
|
-
|pypi-badge| |CI| |codecov-badge| |doc-badge| |pyversions-badge|
|
|
48
|
-
|license-badge|
|
|
49
|
-
|
|
50
49
|
Extensible tools for parsing annotations in codebases
|
|
51
50
|
|
|
52
51
|
Overview
|
|
@@ -100,31 +99,6 @@ refer to this `list of resources`_ if you need any assistance.
|
|
|
100
99
|
.. _list of resources: https://open.edx.org/getting-help
|
|
101
100
|
|
|
102
101
|
|
|
103
|
-
.. |pypi-badge| image:: https://img.shields.io/pypi/v/code-annotations.svg
|
|
104
|
-
:target: https://pypi.python.org/pypi/code-annotations/
|
|
105
|
-
:alt: PyPI
|
|
106
|
-
|
|
107
|
-
.. |CI| image:: https://github.com/openedx/code-annotations/workflows/Python%20CI/badge.svg?branch=master
|
|
108
|
-
:target: https://github.com/openedx/code-annotations/actions?query=workflow%3A%22Python+CI%22
|
|
109
|
-
:alt: CI
|
|
110
|
-
|
|
111
|
-
.. |codecov-badge| image:: http://codecov.io/github/edx/code-annotations/coverage.svg?branch=master
|
|
112
|
-
:target: http://codecov.io/github/edx/code-annotations?branch=master
|
|
113
|
-
:alt: Codecov
|
|
114
|
-
|
|
115
|
-
.. |doc-badge| image:: https://readthedocs.org/projects/code-annotations/badge/?version=latest
|
|
116
|
-
:target: http://code-annotations.readthedocs.io/en/latest/
|
|
117
|
-
:alt: Documentation
|
|
118
|
-
|
|
119
|
-
.. |pyversions-badge| image:: https://img.shields.io/pypi/pyversions/code-annotations.svg
|
|
120
|
-
:target: https://pypi.python.org/pypi/code-annotations/
|
|
121
|
-
:alt: Supported Python versions
|
|
122
|
-
|
|
123
|
-
.. |license-badge| image:: https://img.shields.io/github/license/edx/code-annotations.svg
|
|
124
|
-
:target: https://github.com/openedx/code-annotations/blob/master/LICENSE.txt
|
|
125
|
-
:alt: License
|
|
126
|
-
|
|
127
|
-
|
|
128
102
|
Change Log
|
|
129
103
|
----------
|
|
130
104
|
|
|
@@ -34,6 +34,15 @@ code_annotations/extensions/__init__.py
|
|
|
34
34
|
code_annotations/extensions/base.py
|
|
35
35
|
code_annotations/extensions/javascript.py
|
|
36
36
|
code_annotations/extensions/python.py
|
|
37
|
+
code_annotations/report_templates/html/annotation.tpl
|
|
38
|
+
code_annotations/report_templates/html/annotation_data.tpl
|
|
39
|
+
code_annotations/report_templates/html/annotation_list.tpl
|
|
40
|
+
code_annotations/report_templates/html/base.tpl
|
|
41
|
+
code_annotations/report_templates/rst/annotation.tpl
|
|
42
|
+
code_annotations/report_templates/rst/annotation_data.tpl
|
|
43
|
+
code_annotations/report_templates/rst/annotation_group.tpl
|
|
44
|
+
code_annotations/report_templates/rst/annotation_list.tpl
|
|
45
|
+
code_annotations/report_templates/rst/base.tpl
|
|
37
46
|
requirements/base.in
|
|
38
47
|
tests/test_base.py
|
|
39
48
|
tests/test_django_coverage.py
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""
|
|
3
|
+
Package metadata for code_annotations.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
from setuptools import setup
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_version(*file_paths):
|
|
14
|
+
"""
|
|
15
|
+
Extract the version string from the file at the given relative path fragments.
|
|
16
|
+
"""
|
|
17
|
+
filename = os.path.join(os.path.dirname(__file__), *file_paths)
|
|
18
|
+
version_file = open(filename).read()
|
|
19
|
+
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M)
|
|
20
|
+
if version_match:
|
|
21
|
+
return version_match.group(1)
|
|
22
|
+
raise RuntimeError("Unable to find version string.")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def load_requirements(*requirements_paths):
|
|
26
|
+
"""
|
|
27
|
+
Load all requirements from the specified requirements files.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
list: Requirements file relative path strings
|
|
31
|
+
"""
|
|
32
|
+
requirements = set()
|
|
33
|
+
for path in requirements_paths:
|
|
34
|
+
requirements.update(
|
|
35
|
+
line.split("#")[0].strip()
|
|
36
|
+
for line in open(path).readlines()
|
|
37
|
+
if is_requirement(line.strip())
|
|
38
|
+
)
|
|
39
|
+
return list(requirements)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def is_requirement(line):
|
|
43
|
+
"""
|
|
44
|
+
Return True if the requirement line is a package requirement.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
bool: True if the line is not blank, a comment, a URL, or an included file
|
|
48
|
+
"""
|
|
49
|
+
return not (
|
|
50
|
+
line == ""
|
|
51
|
+
or line.startswith("-r")
|
|
52
|
+
or line.startswith("#")
|
|
53
|
+
or line.startswith("-e")
|
|
54
|
+
or line.startswith("git+")
|
|
55
|
+
or line.startswith("-c")
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
VERSION = get_version("code_annotations", "__init__.py")
|
|
60
|
+
|
|
61
|
+
if sys.argv[-1] == "tag":
|
|
62
|
+
print("Tagging the version on github:")
|
|
63
|
+
os.system("git tag -a %s -m 'version %s'" % (VERSION, VERSION))
|
|
64
|
+
os.system("git push --tags")
|
|
65
|
+
sys.exit()
|
|
66
|
+
|
|
67
|
+
README = open(os.path.join(os.path.dirname(__file__), "README.rst")).read()
|
|
68
|
+
CHANGELOG = open(os.path.join(os.path.dirname(__file__), "CHANGELOG.rst")).read()
|
|
69
|
+
|
|
70
|
+
setup(
|
|
71
|
+
name="code-annotations",
|
|
72
|
+
version=VERSION,
|
|
73
|
+
description="""Extensible tools for parsing annotations in codebases""",
|
|
74
|
+
long_description=README + "\n\n" + CHANGELOG,
|
|
75
|
+
long_description_content_type="text/x-rst",
|
|
76
|
+
author="edX",
|
|
77
|
+
author_email="oscm@edx.org",
|
|
78
|
+
url="https://github.com/openedx/code-annotations",
|
|
79
|
+
packages=[
|
|
80
|
+
"code_annotations",
|
|
81
|
+
],
|
|
82
|
+
entry_points={
|
|
83
|
+
"console_scripts": [
|
|
84
|
+
"code_annotations = code_annotations.cli:entry_point",
|
|
85
|
+
],
|
|
86
|
+
"annotation_finder.searchers": [
|
|
87
|
+
"javascript = code_annotations.extensions.javascript:JavascriptAnnotationExtension",
|
|
88
|
+
"python = code_annotations.extensions.python:PythonAnnotationExtension",
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
include_package_data=True,
|
|
92
|
+
install_requires=load_requirements("requirements/base.in"),
|
|
93
|
+
extras_require={"django": ["Django>=4.2"]},
|
|
94
|
+
license="Apache Software License 2.0",
|
|
95
|
+
zip_safe=False,
|
|
96
|
+
keywords="edx pii code annotations",
|
|
97
|
+
python_requires=">=3.11",
|
|
98
|
+
classifiers=[
|
|
99
|
+
"Development Status :: 3 - Alpha",
|
|
100
|
+
"Framework :: Django",
|
|
101
|
+
"Framework :: Django :: 4.2",
|
|
102
|
+
"Framework :: Django :: 5.2",
|
|
103
|
+
"Intended Audience :: Developers",
|
|
104
|
+
"License :: OSI Approved :: Apache Software License",
|
|
105
|
+
"Natural Language :: English",
|
|
106
|
+
"Programming Language :: Python",
|
|
107
|
+
"Programming Language :: Python :: 3",
|
|
108
|
+
"Programming Language :: Python :: 3.11",
|
|
109
|
+
"Programming Language :: Python :: 3.12",
|
|
110
|
+
],
|
|
111
|
+
)
|
|
@@ -49,6 +49,40 @@ def test_generate_report_simple():
|
|
|
49
49
|
assert os.path.exists(created_doc)
|
|
50
50
|
|
|
51
51
|
|
|
52
|
+
def test_generate_report_simple_html():
|
|
53
|
+
find_result = call_script(
|
|
54
|
+
(
|
|
55
|
+
'static_find_annotations',
|
|
56
|
+
'--config_file',
|
|
57
|
+
'tests/test_configurations/.annotations_test_python_only',
|
|
58
|
+
'--source_path=tests/extensions/python_test_files/simple_success.pyt',
|
|
59
|
+
'--no_lint',
|
|
60
|
+
),
|
|
61
|
+
delete_test_reports=False)
|
|
62
|
+
|
|
63
|
+
assert find_result.exit_code == EXIT_CODE_SUCCESS
|
|
64
|
+
assert "Writing report..." in find_result.output
|
|
65
|
+
report_file = get_report_filename_from_output(find_result.output)
|
|
66
|
+
|
|
67
|
+
report_result = call_script(
|
|
68
|
+
(
|
|
69
|
+
'generate_docs',
|
|
70
|
+
report_file,
|
|
71
|
+
'--config_file',
|
|
72
|
+
'tests/test_configurations/.annotations_test_success_with_report_docs_html',
|
|
73
|
+
'-vv'
|
|
74
|
+
),
|
|
75
|
+
delete_test_docs=False
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
assert find_result.exit_code == EXIT_CODE_SUCCESS
|
|
79
|
+
assert "Report rendered in" in report_result.output
|
|
80
|
+
|
|
81
|
+
# All file types are created
|
|
82
|
+
for created_doc in ('test_reports/index.html', 'test_reports/choice-id.html', 'test_reports/annotation-pii.html'):
|
|
83
|
+
assert os.path.exists(created_doc)
|
|
84
|
+
|
|
85
|
+
|
|
52
86
|
def _do_find(source_path, new_report_path):
|
|
53
87
|
"""
|
|
54
88
|
Do a static annotation search with report, rename the report to a distinct name.
|
|
@@ -167,4 +201,4 @@ def test_generate_report_missing_key():
|
|
|
167
201
|
))
|
|
168
202
|
|
|
169
203
|
assert report_result.exit_code == EXIT_CODE_FAILURE
|
|
170
|
-
assert "No
|
|
204
|
+
assert "No rendered_report_source_link_prefix key in" in report_result.output
|
code_annotations-2.2.0/setup.py
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
"""
|
|
3
|
-
Package metadata for code_annotations.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import os
|
|
7
|
-
import re
|
|
8
|
-
import sys
|
|
9
|
-
|
|
10
|
-
from setuptools import setup
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def get_version(*file_paths):
|
|
14
|
-
"""
|
|
15
|
-
Extract the version string from the file at the given relative path fragments.
|
|
16
|
-
"""
|
|
17
|
-
filename = os.path.join(os.path.dirname(__file__), *file_paths)
|
|
18
|
-
version_file = open(filename).read()
|
|
19
|
-
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
|
|
20
|
-
version_file, re.M)
|
|
21
|
-
if version_match:
|
|
22
|
-
return version_match.group(1)
|
|
23
|
-
raise RuntimeError('Unable to find version string.')
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def load_requirements(*requirements_paths):
|
|
27
|
-
"""
|
|
28
|
-
Load all requirements from the specified requirements files.
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
list: Requirements file relative path strings
|
|
32
|
-
"""
|
|
33
|
-
requirements = set()
|
|
34
|
-
for path in requirements_paths:
|
|
35
|
-
requirements.update(
|
|
36
|
-
line.split('#')[0].strip() for line in open(path).readlines()
|
|
37
|
-
if is_requirement(line.strip())
|
|
38
|
-
)
|
|
39
|
-
return list(requirements)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def is_requirement(line):
|
|
43
|
-
"""
|
|
44
|
-
Return True if the requirement line is a package requirement.
|
|
45
|
-
|
|
46
|
-
Returns:
|
|
47
|
-
bool: True if the line is not blank, a comment, a URL, or an included file
|
|
48
|
-
"""
|
|
49
|
-
return not (
|
|
50
|
-
line == '' or
|
|
51
|
-
line.startswith('-r') or
|
|
52
|
-
line.startswith('#') or
|
|
53
|
-
line.startswith('-e') or
|
|
54
|
-
line.startswith('git+') or
|
|
55
|
-
line.startswith('-c')
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
VERSION = get_version('code_annotations', '__init__.py')
|
|
60
|
-
|
|
61
|
-
if sys.argv[-1] == 'tag':
|
|
62
|
-
print("Tagging the version on github:")
|
|
63
|
-
os.system("git tag -a %s -m 'version %s'" % (VERSION, VERSION))
|
|
64
|
-
os.system("git push --tags")
|
|
65
|
-
sys.exit()
|
|
66
|
-
|
|
67
|
-
README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
|
|
68
|
-
CHANGELOG = open(os.path.join(os.path.dirname(__file__), 'CHANGELOG.rst')).read()
|
|
69
|
-
|
|
70
|
-
setup(
|
|
71
|
-
name='code-annotations',
|
|
72
|
-
version=VERSION,
|
|
73
|
-
description="""Extensible tools for parsing annotations in codebases""",
|
|
74
|
-
long_description=README + '\n\n' + CHANGELOG,
|
|
75
|
-
long_description_content_type='text/x-rst',
|
|
76
|
-
author='edX',
|
|
77
|
-
author_email='oscm@edx.org',
|
|
78
|
-
url='https://github.com/openedx/code-annotations',
|
|
79
|
-
packages=[
|
|
80
|
-
'code_annotations',
|
|
81
|
-
],
|
|
82
|
-
entry_points={
|
|
83
|
-
'console_scripts': [
|
|
84
|
-
'code_annotations = code_annotations.cli:entry_point',
|
|
85
|
-
],
|
|
86
|
-
'annotation_finder.searchers': [
|
|
87
|
-
'javascript = code_annotations.extensions.javascript:JavascriptAnnotationExtension',
|
|
88
|
-
'python = code_annotations.extensions.python:PythonAnnotationExtension',
|
|
89
|
-
],
|
|
90
|
-
},
|
|
91
|
-
include_package_data=True,
|
|
92
|
-
install_requires=load_requirements('requirements/base.in'),
|
|
93
|
-
extras_require={"django": ["Django>=4.2"]},
|
|
94
|
-
license="Apache Software License 2.0",
|
|
95
|
-
zip_safe=False,
|
|
96
|
-
keywords='edx pii code annotations',
|
|
97
|
-
python_requires=">=3.11",
|
|
98
|
-
classifiers=[
|
|
99
|
-
'Development Status :: 3 - Alpha',
|
|
100
|
-
'Framework :: Django',
|
|
101
|
-
'Framework :: Django :: 4.2',
|
|
102
|
-
'Intended Audience :: Developers',
|
|
103
|
-
'License :: OSI Approved :: Apache Software License',
|
|
104
|
-
'Natural Language :: English',
|
|
105
|
-
'Programming Language :: Python',
|
|
106
|
-
'Programming Language :: Python :: 3',
|
|
107
|
-
'Programming Language :: Python :: 3.11',
|
|
108
|
-
'Programming Language :: Python :: 3.12',
|
|
109
|
-
],
|
|
110
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/config/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations/contrib/sphinx/extensions/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{code_annotations-2.2.0 → code_annotations-2.3.0}/code_annotations.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|