pycodetags-issue-tracker 0.2.0__tar.gz → 0.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.
Files changed (76) hide show
  1. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.gitignore +1 -0
  2. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.pycodetags_cache/3abd8b86451a3bed58e5508d50755fa7162e61c07f4c38dfdb92821905218424.pkl.gz +0 -0
  3. pycodetags_issue_tracker-0.3.0/.pycodetags_cache/50c0ba17a34254498b1f0b12c34c5a710f71cb2023e647d6d18fba7fd4533644.pkl.gz +0 -0
  4. pycodetags_issue_tracker-0.3.0/.pycodetags_cache/5ec5aaeef2ce0c638d3815c404ad8e6ae58ac2db887cb2d224830dd772ec599a.pkl.gz +0 -0
  5. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.pycodetags_cache/bb68338365ca411e6eb797220212da263ee87eb36945f1971f93f0e2f492ed29.pkl.gz +0 -0
  6. pycodetags_issue_tracker-0.3.0/.pycodetags_cache/df605264730bee885e8f35dfb9f5490f17c87a2b526facd1095eb56af854703a.pkl.gz +0 -0
  7. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/Makefile +2 -2
  8. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/PKG-INFO +2 -2
  9. pycodetags_issue_tracker-0.3.0/make_prompt.sh +84 -0
  10. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/__about__.py +1 -1
  11. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/__init__.py +2 -2
  12. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/cli.py +15 -7
  13. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/config}/issue_tracker_config.py +3 -3
  14. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/converters.py +6 -6
  15. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/main.py +11 -3
  16. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/plugin_specs.py +2 -3
  17. pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/schema/__init__.py +0 -0
  18. pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker/todo_tag_types_aliases.py → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/schema/issue_tracker_aliases.py +1 -12
  19. pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker/todo_tag_types.py → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/schema/issue_tracker_classes.py +5 -6
  20. pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/schema/issue_tracker_schema.py +187 -0
  21. pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/user_utils/__init__.py +0 -0
  22. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/user_utils}/user.py +1 -0
  23. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/user_utils}/users_from_authors.py +0 -33
  24. pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/views/__init__.py +9 -0
  25. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/views}/health_o_meter.py +1 -1
  26. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/views}/templates/report.html.jinja2 +26 -4
  27. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/views}/views.py +3 -2
  28. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/views}/views_templated.py +6 -4
  29. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pyproject.toml +2 -3
  30. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/scripts}/todo_tag_types_generate_aliases.py +1 -1
  31. pycodetags_issue_tracker-0.3.0/tests/__init__.py +0 -0
  32. pycodetags_issue_tracker-0.3.0/tests/test_config/__init__.py +0 -0
  33. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/tests/test_converters.py +0 -4
  34. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/tests/test_dates.py +1 -1
  35. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/tests/test_exercise_factories.py +1 -1
  36. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/tests/test_folk_tags.py +0 -2
  37. pycodetags_issue_tracker-0.3.0/tests/test_schema/__init__.py +0 -0
  38. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_schema}/test_TODO.py +1 -1
  39. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_schema}/test_done.py +1 -1
  40. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_schema}/test_pep350_tags_doubles.py +13 -93
  41. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_schema}/test_standard_code_tags.py +9 -8
  42. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_schema}/test_tag_types_generate_aliases.py +1 -1
  43. pycodetags_issue_tracker-0.3.0/tests/test_user/__init__.py +0 -0
  44. pycodetags_issue_tracker-0.3.0/tests/test_user/test_example.py +30 -0
  45. pycodetags_issue_tracker-0.3.0/tests/test_user_utils/__init__.py +0 -0
  46. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_user_utils}/test_user.py +1 -1
  47. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_user_utils}/test_user_more.py +2 -1
  48. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_user_utils}/test_users_from_authors.py +1 -1
  49. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_user_utils}/test_users_from_authors_more.py +1 -1
  50. pycodetags_issue_tracker-0.3.0/tests/test_views/__init__.py +0 -0
  51. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_views}/test_views.py +2 -2
  52. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_views}/test_views_with_just_any_data.py +1 -1
  53. pycodetags_issue_tracker-0.2.0/.pycodetags_cache/50c0ba17a34254498b1f0b12c34c5a710f71cb2023e647d6d18fba7fd4533644.pkl.gz +0 -0
  54. pycodetags_issue_tracker-0.2.0/.pycodetags_cache/5ec5aaeef2ce0c638d3815c404ad8e6ae58ac2db887cb2d224830dd772ec599a.pkl.gz +0 -0
  55. pycodetags_issue_tracker-0.2.0/.pycodetags_cache/df605264730bee885e8f35dfb9f5490f17c87a2b526facd1095eb56af854703a.pkl.gz +0 -0
  56. pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker/issue_tracker_schema.py +0 -49
  57. pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker/standard_code_tags.py +0 -147
  58. pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker/todo_object_schema.py +0 -32
  59. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.markdownlintrc +0 -0
  60. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.pycodetags_cache/.gitignore +0 -0
  61. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.pylintrc +0 -0
  62. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.pylintrc_docs +0 -0
  63. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.pylintrc_spell +0 -0
  64. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/.pylintrc_tests +0 -0
  65. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/README.md +0 -0
  66. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/configs_for_methologies/pep350.toml +0 -0
  67. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/configs_for_methologies/pycodetags.toml +0 -0
  68. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/configs_for_methologies/scrum.toml +0 -0
  69. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/_tag_templates.txt.md +0 -0
  70. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/config}/__init__.py +0 -0
  71. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/pycodetags_issue_tracker/plugin_manager.py +0 -0
  72. {pycodetags_issue_tracker-0.2.0/pycodetags_issue_tracker → pycodetags_issue_tracker-0.3.0/pycodetags_issue_tracker/views}/templates/__init__.py +0 -0
  73. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_config}/test_config_more.py +0 -0
  74. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/tests/test_import.py +0 -0
  75. {pycodetags_issue_tracker-0.2.0/tests → pycodetags_issue_tracker-0.3.0/tests/test_schema}/test_todos_again.py +0 -0
  76. {pycodetags_issue_tracker-0.2.0 → pycodetags_issue_tracker-0.3.0}/tox.ini +0 -0
@@ -195,3 +195,4 @@ cython_debug/
195
195
  /pydocs/
196
196
  .build_history
197
197
  .cli_tool_audit_cache
198
+ /docs_site/output/
@@ -21,8 +21,8 @@ black:
21
21
  @echo "Formatting code"
22
22
  $(VENV) metametameta pep621
23
23
  $(VENV) isort .
24
- $(VENV) black pycodetags_issue_tracker --exclude .venv
25
- $(VENV) black tests --exclude .venv
24
+ $(VENV) black pycodetags_issue_tracker # --exclude .venv
25
+ $(VENV) black tests # --exclude .venv
26
26
  $(VENV) coderoller-flatten-repo pycodetags_issue_tracker
27
27
 
28
28
  .PHONY: bandit
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycodetags-issue-tracker
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Plugin for pycodetags to track issues, e.g. bugs, TODO, etc in your code
5
5
  Author-email: Matthew Martin <matthewdeanmartin@gmail.com>
6
6
  License-Expression: MIT
@@ -22,7 +22,7 @@ Requires-Python: >=3.7
22
22
  Requires-Dist: importlib-resources; python_version < '3.9'
23
23
  Requires-Dist: jinja2
24
24
  Requires-Dist: pluggy
25
- Requires-Dist: pycodetags>=0.5.0
25
+ Requires-Dist: pycodetags>=0.6.0
26
26
  Requires-Dist: toml; python_version < '3.11'
27
27
  Requires-Dist: typing-extensions; python_version < '3.8'
28
28
  Description-Content-Type: text/markdown
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # readonly SCRIPT_NS="pycodetags_proc"
5
+ readonly SRC_DIR="./pycodetags_issue_tracker"
6
+ readonly TMP_ROOT="/tmp"
7
+ readonly TMP_DIR="${TMP_ROOT}/pycodetags_issue_tracker"
8
+
9
+ # Copy directory safely
10
+ pycodetags_proc::copy_to_tmp() {
11
+ if [[ ! -d "${SRC_DIR}" ]]; then
12
+ echo "Error: Source directory '${SRC_DIR}' not found." >&2
13
+ exit 1
14
+ fi
15
+
16
+ echo "Copying '${SRC_DIR}' to '${TMP_DIR}'..."
17
+ rm -rf "${TMP_DIR}"
18
+ cp -a "${SRC_DIR}" "${TMP_DIR}"
19
+ }
20
+
21
+ # Run strip-docs for each subdirectory of tmp/pycodetags
22
+ pycodetags_proc::run_strip_docs() {
23
+ local dir
24
+ echo "Running strip-docs on '${TMP_DIR}' and subdirectories..."
25
+
26
+ while IFS= read -r -d '' dir; do
27
+ echo "→ strip-docs on '${dir}'"
28
+ strip-docs "${dir}"
29
+ done < <(find "${TMP_DIR}" -type d -print0)
30
+ }
31
+
32
+ # Ask for confirmation before proceeding
33
+ pycodetags_proc::confirm() {
34
+ local prompt="$1"
35
+
36
+ if [[ -z "${CAUTION:-}" ]]; then
37
+ echo "Skipping prompt: CAUTION not set."
38
+ return 0
39
+ fi
40
+
41
+ read -rp "${prompt} [y/N] " response
42
+ if [[ "${response}" =~ ^[Yy]$ ]]; then
43
+ return 0
44
+ else
45
+ echo "Aborted." >&2
46
+ exit 1
47
+ fi
48
+ }
49
+
50
+
51
+ # Run coderoller-flatten-repo
52
+ pycodetags_proc::flatten_repo() {
53
+ echo "Removing marker lines from .py files in '${TMP_DIR}'..."
54
+
55
+ find "${TMP_DIR}" -type f -name '*.py' -print0 | while IFS= read -r -d '' file; do
56
+ # Remove lines that are exactly " ##" or " #--" (whitespace-sensitive)
57
+ sed -i '/^[[:space:]]*##[[:space:]]*$/d;/^[[:space:]]*#--[[:space:]]*$/d' "$file"
58
+ done
59
+
60
+ echo "Running black on '${TMP_DIR}'..."
61
+ set +e
62
+ black "${TMP_DIR}"
63
+ set -e
64
+
65
+ echo "Running coderoller-flatten-repo on '${TMP_DIR}'..."
66
+ coderoller-flatten-repo "${TMP_DIR}"
67
+ }
68
+
69
+ # Cleanup tmp directory
70
+ pycodetags_proc::cleanup_tmp() {
71
+ echo "Cleaning up '${TMP_DIR}'..."
72
+ rm -rf "${TMP_DIR}"
73
+ }
74
+
75
+ main() {
76
+ pycodetags_proc::copy_to_tmp
77
+ pycodetags_proc::run_strip_docs
78
+ pycodetags_proc::confirm "Run coderoller-flatten-repo?"
79
+ pycodetags_proc::flatten_repo
80
+ pycodetags_proc::confirm "Delete temporary files in '${TMP_DIR}'?"
81
+ pycodetags_proc::cleanup_tmp
82
+ }
83
+
84
+ [[ "${BASH_SOURCE[0]}" == "$0" ]] && main "$@"
@@ -17,7 +17,7 @@ __all__ = [
17
17
  ]
18
18
 
19
19
  __title__ = "pycodetags-issue-tracker"
20
- __version__ = "0.1.1"
20
+ __version__ = "0.2.0"
21
21
  __description__ = "Plugin for pycodetags to track issues, e.g. bugs, TODO, etc in your code"
22
22
  __readme__ = "README.md"
23
23
  __keywords__ = ["pep350", "pep-350", "codetag", "codetags", "code-tags", "code-tag", "TODO", "FIXME", "pycodetags"]
@@ -13,8 +13,7 @@ __all__ = [
13
13
  "DOCUMENT",
14
14
  ]
15
15
 
16
- from pycodetags_issue_tracker.todo_tag_types import TODO
17
- from pycodetags_issue_tracker.todo_tag_types_aliases import (
16
+ from pycodetags_issue_tracker.schema.issue_tracker_aliases import (
18
17
  ALERT,
19
18
  BUG,
20
19
  CLEVER,
@@ -27,3 +26,4 @@ from pycodetags_issue_tracker.todo_tag_types_aliases import (
27
26
  REQUIREMENT,
28
27
  STORY,
29
28
  )
29
+ from pycodetags_issue_tracker.schema.issue_tracker_classes import TODO
@@ -5,10 +5,18 @@ import sys
5
5
  from collections.abc import Sequence
6
6
  from typing import cast
7
7
 
8
- from pycodetags_issue_tracker import TODO, views, views_templated
8
+ from pycodetags_issue_tracker import TODO
9
+ from pycodetags_issue_tracker.views import views_templated
10
+ from pycodetags_issue_tracker.views.views import (
11
+ print_changelog,
12
+ print_done_file,
13
+ print_text,
14
+ print_todo_md,
15
+ print_validate,
16
+ )
9
17
 
10
18
  from pycodetags import DATA
11
- from pycodetags.config import CodeTagsConfig
19
+ from pycodetags.app_config.config import CodeTagsConfig
12
20
 
13
21
 
14
22
  def handle_cli(subparsers: argparse._SubParsersAction):
@@ -53,23 +61,23 @@ def run_cli_command(
53
61
  # args.output
54
62
  if command_name == "issues":
55
63
  if format_name == "validate":
56
- if views.print_validate(cast(list[TODO], found_data)):
64
+ if print_validate(cast(list[TODO], found_data)):
57
65
  sys.exit(100)
58
66
  return True
59
67
  if format_name == "html":
60
68
  views_templated.print_html(cast(list[TODO], found_data))
61
69
  return True
62
70
  if format_name == "todomd":
63
- views.print_todo_md(cast(list[TODO], found_data))
71
+ print_todo_md(cast(list[TODO], found_data))
64
72
  return True
65
73
  if format_name == "text":
66
- views.print_text(cast(list[TODO], found_data))
74
+ print_text(cast(list[TODO], found_data))
67
75
  return True
68
76
  if format_name == "changelog":
69
- views.print_changelog(cast(list[TODO], found_data))
77
+ print_changelog(cast(list[TODO], found_data))
70
78
  return True
71
79
  if format_name == "donefile":
72
- views.print_done_file(cast(list[TODO], found_data))
80
+ print_done_file(cast(list[TODO], found_data))
73
81
  return True
74
82
  return False
75
83
  return False
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from pycodetags_issue_tracker.user import get_current_user
4
- from pycodetags_issue_tracker.users_from_authors import parse_authors_file_simple
3
+ from pycodetags_issue_tracker.user_utils.user import get_current_user
4
+ from pycodetags_issue_tracker.user_utils.users_from_authors import parse_authors_file_simple
5
5
 
6
- from pycodetags.config import CodeTagsConfig, careful_to_bool, get_code_tags_config
6
+ from pycodetags.app_config.config import CodeTagsConfig, careful_to_bool, get_code_tags_config
7
7
 
8
8
 
9
9
  class IssueTrackerConfig:
@@ -8,12 +8,12 @@ import logging
8
8
  from collections.abc import Iterable
9
9
  from typing import Any
10
10
 
11
- from pycodetags_issue_tracker.todo_object_schema import TODO_KEYWORDS
12
- from pycodetags_issue_tracker.todo_tag_types import TODO
11
+ from pycodetags_issue_tracker.schema.issue_tracker_classes import TODO
12
+ from pycodetags_issue_tracker.schema.issue_tracker_schema import IssueTrackerSchema, data_fields_as_list
13
13
 
14
14
  from pycodetags import DATA
15
- from pycodetags.data_tags_schema import DataTag
16
- from pycodetags.folk_tags_parser import FolkTag
15
+ from pycodetags.data_tags import DataTag
16
+ from pycodetags.folk_tags import FolkTag
17
17
 
18
18
  logger = logging.getLogger(__name__)
19
19
 
@@ -101,7 +101,7 @@ def convert_folk_tag_to_TODO(folk_tag: FolkTag) -> TODO:
101
101
  "offsets": folk_tag.get("offsets"),
102
102
  }
103
103
  custom_fields = folk_tag.get("custom_fields", {})
104
- for keyword in TODO_KEYWORDS:
104
+ for keyword in data_fields_as_list(IssueTrackerSchema):
105
105
  for field_key, field_value in custom_fields.items():
106
106
  # Promote custom fields to kwargs if they match the keyword
107
107
  # and the keyword is not already in kwargs
@@ -147,7 +147,7 @@ def convert_pep350_tag_to_TODO(pep350_tag: DataTag) -> TODO:
147
147
  }
148
148
 
149
149
  custom_fields = pep350_tag["fields"].get("custom_fields", {})
150
- for keyword in TODO_KEYWORDS:
150
+ for keyword in data_fields_as_list(IssueTrackerSchema):
151
151
  for field_key, field_value in custom_fields.items():
152
152
  # Promote custom fields to kwargs if they match the keyword
153
153
  # and the keyword is not already in kwargs
@@ -5,17 +5,18 @@ Registry of plugin hooks. These are exported via "entrypoints".
5
5
  from __future__ import annotations
6
6
 
7
7
  import argparse
8
- from collections.abc import Callable, Sequence
8
+ from collections.abc import Sequence
9
+ from typing import Callable # noqa
9
10
 
10
11
  import pluggy
11
12
  from pluggy import HookimplMarker
12
13
  from pycodetags_issue_tracker import cli
13
14
  from pycodetags_issue_tracker.converters import convert_data_to_TODO
14
- from pycodetags_issue_tracker.issue_tracker_schema import IssueTrackerSchema
15
15
  from pycodetags_issue_tracker.plugin_manager import set_plugin_manager
16
+ from pycodetags_issue_tracker.schema.issue_tracker_schema import IssueTrackerSchema
16
17
 
17
18
  from pycodetags import DATA, DataTagSchema
18
- from pycodetags.config import CodeTagsConfig
19
+ from pycodetags.app_config.config import CodeTagsConfig
19
20
 
20
21
  hookimpl = HookimplMarker("pycodetags")
21
22
 
@@ -82,5 +83,12 @@ class IssueTrackerApp:
82
83
  # This doesn't work for domain specific TODOs
83
84
  return []
84
85
 
86
+ @hookimpl
87
+ def provide_schemas(self) -> list[DataTagSchema]:
88
+ """
89
+ Return one or more schema definitions provided by this plugin.
90
+ """
91
+ return [IssueTrackerSchema]
92
+
85
93
 
86
94
  issue_tracker_app_plugin = IssueTrackerApp()
@@ -9,9 +9,8 @@ import argparse
9
9
 
10
10
  import pluggy
11
11
 
12
- from pycodetags.config import CodeTagsConfig
13
- from pycodetags.data_tags_classes import DATA
14
- from pycodetags.data_tags_schema import DataTag
12
+ from pycodetags.app_config import CodeTagsConfig
13
+ from pycodetags.data_tags import DATA, DataTag
15
14
 
16
15
  hookspec = pluggy.HookspecMarker("pycodetags")
17
16
 
@@ -4,7 +4,7 @@ Aliases for TODO
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- from pycodetags_issue_tracker.todo_tag_types import TODO
7
+ from pycodetags_issue_tracker.schema.issue_tracker_classes import TODO
8
8
 
9
9
 
10
10
  def REQUIREMENT(
@@ -21,7 +21,6 @@ def REQUIREMENT(
21
21
  closed_comment: str | None = None,
22
22
  tracker: str | None = None,
23
23
  file_path: str | None = None,
24
-
25
24
  original_text: str | None = None,
26
25
  original_schema: str | None = None,
27
26
  custom_fields: dict[str, str] | None = None,
@@ -68,7 +67,6 @@ def STORY(
68
67
  closed_comment: str | None = None,
69
68
  tracker: str | None = None,
70
69
  file_path: str | None = None,
71
-
72
70
  original_text: str | None = None,
73
71
  original_schema: str | None = None,
74
72
  custom_fields: dict[str, str] | None = None,
@@ -115,7 +113,6 @@ def IDEA(
115
113
  closed_comment: str | None = None,
116
114
  tracker: str | None = None,
117
115
  file_path: str | None = None,
118
-
119
116
  original_text: str | None = None,
120
117
  original_schema: str | None = None,
121
118
  custom_fields: dict[str, str] | None = None,
@@ -162,7 +159,6 @@ def FIXME(
162
159
  closed_comment: str | None = None,
163
160
  tracker: str | None = None,
164
161
  file_path: str | None = None,
165
-
166
162
  original_text: str | None = None,
167
163
  original_schema: str | None = None,
168
164
  custom_fields: dict[str, str] | None = None,
@@ -209,7 +205,6 @@ def BUG(
209
205
  closed_comment: str | None = None,
210
206
  tracker: str | None = None,
211
207
  file_path: str | None = None,
212
-
213
208
  original_text: str | None = None,
214
209
  original_schema: str | None = None,
215
210
  custom_fields: dict[str, str] | None = None,
@@ -256,7 +251,6 @@ def HACK(
256
251
  closed_comment: str | None = None,
257
252
  tracker: str | None = None,
258
253
  file_path: str | None = None,
259
-
260
254
  original_text: str | None = None,
261
255
  original_schema: str | None = None,
262
256
  custom_fields: dict[str, str] | None = None,
@@ -303,7 +297,6 @@ def CLEVER(
303
297
  closed_comment: str | None = None,
304
298
  tracker: str | None = None,
305
299
  file_path: str | None = None,
306
-
307
300
  original_text: str | None = None,
308
301
  original_schema: str | None = None,
309
302
  custom_fields: dict[str, str] | None = None,
@@ -350,7 +343,6 @@ def MAGIC(
350
343
  closed_comment: str | None = None,
351
344
  tracker: str | None = None,
352
345
  file_path: str | None = None,
353
-
354
346
  original_text: str | None = None,
355
347
  original_schema: str | None = None,
356
348
  custom_fields: dict[str, str] | None = None,
@@ -397,7 +389,6 @@ def ALERT(
397
389
  closed_comment: str | None = None,
398
390
  tracker: str | None = None,
399
391
  file_path: str | None = None,
400
-
401
392
  original_text: str | None = None,
402
393
  original_schema: str | None = None,
403
394
  custom_fields: dict[str, str] | None = None,
@@ -444,7 +435,6 @@ def PORT(
444
435
  closed_comment: str | None = None,
445
436
  tracker: str | None = None,
446
437
  file_path: str | None = None,
447
-
448
438
  original_text: str | None = None,
449
439
  original_schema: str | None = None,
450
440
  custom_fields: dict[str, str] | None = None,
@@ -491,7 +481,6 @@ def DOCUMENT(
491
481
  closed_comment: str | None = None,
492
482
  tracker: str | None = None,
493
483
  file_path: str | None = None,
494
-
495
484
  original_text: str | None = None,
496
485
  original_schema: str | None = None,
497
486
  custom_fields: dict[str, str] | None = None,
@@ -12,12 +12,11 @@ from dataclasses import dataclass, field
12
12
  from functools import wraps
13
13
  from typing import Any, Callable, cast # noqa
14
14
 
15
- from pycodetags_issue_tracker.issue_tracker_config import get_issue_tracker_config
16
- from pycodetags_issue_tracker.issue_tracker_schema import IssueTrackerSchema
17
- from pycodetags_issue_tracker.todo_object_schema import TODO_KEYWORDS
15
+ from pycodetags_issue_tracker.config.issue_tracker_config import get_issue_tracker_config
16
+ from pycodetags_issue_tracker.schema.issue_tracker_schema import IssueTrackerSchema, data_fields_as_list
18
17
 
19
- from pycodetags.config import get_code_tags_config
20
- from pycodetags.data_tags_classes import DATA
18
+ from pycodetags.app_config.config import get_code_tags_config
19
+ from pycodetags.data_tags.data_tags_classes import DATA
21
20
 
22
21
  try:
23
22
  from typing import Literal # type:ignore[assignment,unused-ignore]
@@ -341,7 +340,7 @@ class TODO(DATA):
341
340
  self.default_fields[name] = value
342
341
 
343
342
  # data_fields
344
- for name in TODO_KEYWORDS:
343
+ for name in data_fields_as_list(IssueTrackerSchema):
345
344
  value = getattr(self, name)
346
345
  if value is not None:
347
346
  self.data_fields[name] = value
@@ -0,0 +1,187 @@
1
+ from __future__ import annotations
2
+
3
+ from pycodetags.data_tags.data_tags_schema import DataTagSchema, FieldInfo
4
+
5
+ IssueTrackerSchema: DataTagSchema = {
6
+ "name": "TODO",
7
+ "matching_tags": [
8
+ "TODO",
9
+ "REQUIREMENT",
10
+ "STORY",
11
+ "IDEA",
12
+ # Defects
13
+ "FIXME",
14
+ "BUG",
15
+ # Negative sentiment
16
+ "HACK",
17
+ "CLEVER",
18
+ "MAGIC",
19
+ "ALERT",
20
+ # Categories of tasks
21
+ "PORT",
22
+ "DOCUMENT",
23
+ ],
24
+ "default_fields": {"str": "originator", "date": "origination_date"},
25
+ "data_fields": {
26
+ "priority": "str", # or str | int?
27
+ "due": "date",
28
+ "tracker": "str",
29
+ "status": "str",
30
+ "category": "str",
31
+ "iteration": "str", # or str | int?
32
+ "release": "str", # or str | int | version?
33
+ "assignee": "str", # or str | list[str]?
34
+ "originator": "str", # who created the issue
35
+ "origination_date": "date", # when the issue was created
36
+ "closed_date": "date", # when the issue was closed
37
+ "change_type": "str", # e.g. 'Added', 'Changed', 'Deprecated', 'Removed', 'Fixed', 'Security'
38
+ },
39
+ "data_field_aliases": {
40
+ "p": "priority",
41
+ "d": "due",
42
+ "t": "tracker",
43
+ "s": "status",
44
+ "c": "category",
45
+ "i": "iteration",
46
+ "r": "release",
47
+ "a": "assignee",
48
+ },
49
+ "field_infos": {
50
+ "assignee": FieldInfo(
51
+ name="assignee",
52
+ data_type="str",
53
+ valid_values=[],
54
+ label="Assignee",
55
+ description="User who will do the work.",
56
+ aliases=["a"],
57
+ value_on_new="meta.user.name",
58
+ value_on_blank="",
59
+ value_on_delete="",
60
+ ),
61
+ "originator": FieldInfo(
62
+ name="originator",
63
+ data_type="str",
64
+ valid_values=[],
65
+ label="Originator",
66
+ description="User who created the issue.",
67
+ aliases=[],
68
+ value_on_new="meta.user.name",
69
+ value_on_blank="",
70
+ value_on_delete="",
71
+ ),
72
+ "origination_date": FieldInfo(
73
+ name="origination_date",
74
+ data_type="date",
75
+ valid_values=[],
76
+ label="Origination Date",
77
+ description="Date issue created in YYYY-MM-DD format.",
78
+ aliases=[],
79
+ value_on_new="meta.timestamp.date",
80
+ value_on_blank="",
81
+ value_on_delete="",
82
+ ),
83
+ "due": FieldInfo(
84
+ name="due",
85
+ data_type="date",
86
+ valid_values=[],
87
+ label="Due Date",
88
+ description="Date issue will be done in YYYY-MM-DD format.",
89
+ aliases=["d"],
90
+ value_on_new="",
91
+ value_on_blank="",
92
+ value_on_delete="",
93
+ ),
94
+ "release": FieldInfo(
95
+ name="release",
96
+ data_type="str",
97
+ valid_values=[],
98
+ label="Release",
99
+ description="Release completed, will attempt to parse as semantic version A.B.C.",
100
+ aliases=["r"],
101
+ value_on_new="",
102
+ value_on_blank="",
103
+ value_on_delete="meta.project.version",
104
+ ),
105
+ "iteration": FieldInfo(
106
+ name="iteration",
107
+ data_type="str",
108
+ valid_values=[],
109
+ label="Iteration",
110
+ description="User specified meaning, a milestone in a release.",
111
+ aliases=["i"],
112
+ value_on_new="",
113
+ value_on_blank="",
114
+ value_on_delete="",
115
+ ),
116
+ "change_type": FieldInfo(
117
+ name="change_type",
118
+ data_type="str",
119
+ valid_values=["Added", "Changed", "Deprecated", "Removed", "Fixed", "Security"],
120
+ label="Change Type",
121
+ description="Field for Keep a Changelog support.",
122
+ aliases=[],
123
+ value_on_new="",
124
+ value_on_blank="'Changed'",
125
+ value_on_delete="",
126
+ ),
127
+ "closed_date": FieldInfo(
128
+ name="closed_date",
129
+ data_type="date",
130
+ valid_values=[],
131
+ label="Closed Date",
132
+ description="Date issue closed in YYYY-MM-DD format.",
133
+ aliases=[],
134
+ value_on_new="",
135
+ value_on_blank="",
136
+ value_on_delete="meta.timestamp.date",
137
+ ),
138
+ "tracker": FieldInfo(
139
+ name="tracker",
140
+ data_type="str",
141
+ valid_values=[],
142
+ label="Tracker",
143
+ description="A URL or Issue as determined by config or URL detection.",
144
+ aliases=["t"],
145
+ value_on_new="",
146
+ value_on_blank="",
147
+ value_on_delete="",
148
+ ),
149
+ "priority": FieldInfo(
150
+ name="priority",
151
+ data_type="str",
152
+ valid_values=[],
153
+ label="Priority",
154
+ description="User specified meaning, urgency of task.",
155
+ aliases=["p"],
156
+ value_on_new="lookup(meta.priority_map, tag.code_tag) || '2'",
157
+ value_on_blank="lookup(meta.priority_map, tag.code_tag) || '2'",
158
+ value_on_delete="lookup(meta.priority_map, tag.code_tag) || '2'",
159
+ ),
160
+ "status": FieldInfo(
161
+ name="status",
162
+ data_type="str",
163
+ valid_values=[],
164
+ label="Status",
165
+ description="Done, plus other user specified values.",
166
+ aliases=["s"],
167
+ value_on_new="planned",
168
+ value_on_blank="",
169
+ value_on_delete="done",
170
+ ),
171
+ "category": FieldInfo(
172
+ name="category",
173
+ data_type="str",
174
+ valid_values=[],
175
+ label="Category",
176
+ description="User specified meaning, any useful categorization of issues.",
177
+ aliases=["c"],
178
+ value_on_new="",
179
+ value_on_blank="",
180
+ value_on_delete="",
181
+ ),
182
+ },
183
+ }
184
+
185
+
186
+ def data_fields_as_list(schema: DataTagSchema):
187
+ return list(schema["data_fields"].keys())
@@ -7,6 +7,7 @@ from __future__ import annotations
7
7
 
8
8
  import logging
9
9
  import os
10
+
10
11
  # I could use git library but that also uses shell
11
12
  import subprocess # nosec
12
13
  from functools import lru_cache
@@ -5,7 +5,6 @@ Author file parsing.
5
5
  from __future__ import annotations
6
6
 
7
7
  import logging
8
- import os
9
8
  import re
10
9
  from typing import Any
11
10
 
@@ -61,35 +60,3 @@ def parse_authors_file(file_path: str) -> list[dict[str, str | Any]]:
61
60
  print(f"Warning: Could not fully parse line: '{line}'")
62
61
 
63
62
  return authors
64
-
65
-
66
- # --- Example Usage ---
67
- if __name__ == "__main__":
68
-
69
- def example() -> None:
70
- """
71
- Example function to demonstrate how to use the parse_authors_file function.
72
- """
73
- # Create a dummy AUTHORS file for testing
74
- dummy_authors_content = """
75
- # Project Contributors
76
-
77
- John Doe <john.doe@example.com>
78
- Jane Smith
79
- Alice Wonderland <alice@wonderland.org>
80
- Bob The Builder (Maintenance Lead)
81
- # A comment line
82
- Charlie Chaplin
83
- """
84
- with open("AUTHORS_test.txt", "w", encoding="utf-8") as f:
85
- f.write(dummy_authors_content.strip())
86
-
87
- parsed_authors = parse_authors_file("AUTHORS_test.txt")
88
-
89
- print("Parsed Authors:")
90
- for author in parsed_authors:
91
- print(author)
92
-
93
- os.remove("AUTHORS_test.txt")
94
-
95
- example()