package-dev-tools 0.1.1__py3-none-any.whl
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.
- package_dev_tools/__init__.py +0 -0
- package_dev_tools/actions/__init__.py +0 -0
- package_dev_tools/actions/cleanup_readme.py +10 -0
- package_dev_tools/actions/substitute_template_name.py +114 -0
- package_dev_tools/actions/trigger_template_sync.py +36 -0
- package_dev_tools/interfaces/__init__.py +0 -0
- package_dev_tools/interfaces/cli/__init__.py +0 -0
- package_dev_tools/interfaces/cli/check_coverage.py +7 -0
- package_dev_tools/interfaces/cli/cleanup_readme.py +7 -0
- package_dev_tools/interfaces/cli/substitute_template_name.py +7 -0
- package_dev_tools/interfaces/cli/trigger_template_sync.py +7 -0
- package_dev_tools/models/__init__.py +1 -0
- package_dev_tools/models/path.py +14 -0
- package_dev_tools/pre_commit/__init__.py +0 -0
- package_dev_tools/pre_commit/check_coverage.py +85 -0
- package_dev_tools/py.typed +1 -0
- package_dev_tools/utils/__init__.py +0 -0
- package_dev_tools/utils/package/__init__.py +1 -0
- package_dev_tools/utils/package/utils.py +23 -0
- package_dev_tools/utils/tests/__init__.py +1 -0
- package_dev_tools/utils/tests/utils.py +14 -0
- package_dev_tools-0.1.1.data/scripts/check-version +10 -0
- package_dev_tools-0.1.1.data/scripts/cleanup-workflows +4 -0
- package_dev_tools-0.1.1.dist-info/LICENSE +21 -0
- package_dev_tools-0.1.1.dist-info/METADATA +37 -0
- package_dev_tools-0.1.1.dist-info/RECORD +29 -0
- package_dev_tools-0.1.1.dist-info/WHEEL +5 -0
- package_dev_tools-0.1.1.dist-info/entry_points.txt +5 -0
- package_dev_tools-0.1.1.dist-info/top_level.txt +1 -0
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from ..models import Path
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def cleanup_readme() -> None:
|
|
5
|
+
path = Path.readme
|
|
6
|
+
delimiter = "=" * 60 + "\n"
|
|
7
|
+
keyword = "## Usage"
|
|
8
|
+
text_parts = path.text.split(delimiter)
|
|
9
|
+
text_parts[0] = text_parts[0].split(keyword)[0]
|
|
10
|
+
path.text = keyword.join(text_parts)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterator
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
|
|
6
|
+
import cli
|
|
7
|
+
from plib import Path
|
|
8
|
+
from slugify import slugify
|
|
9
|
+
|
|
10
|
+
from package_dev_tools.utils.package import extract_package_name, extract_package_slug
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class Project:
|
|
15
|
+
package_slug: str
|
|
16
|
+
path: Path = Path.cwd()
|
|
17
|
+
|
|
18
|
+
def __post_init__(self) -> None:
|
|
19
|
+
self.check_package_slug()
|
|
20
|
+
self.package_name = slugify(self.package_slug, separator="_")
|
|
21
|
+
self.name = slugify(self.package_slug, separator=" ").title()
|
|
22
|
+
|
|
23
|
+
def check_package_slug(self) -> None:
|
|
24
|
+
is_valid = self.package_slug == slugify(self.package_slug) and self.package_slug
|
|
25
|
+
if not is_valid:
|
|
26
|
+
self.raise_invalid_naming_exception()
|
|
27
|
+
|
|
28
|
+
def raise_invalid_naming_exception(self) -> None:
|
|
29
|
+
suggested_name = slugify(self.package_slug)
|
|
30
|
+
message = (
|
|
31
|
+
f"The project name '{self.package_slug}' is invalid.\n"
|
|
32
|
+
f"Suggested name: {suggested_name}"
|
|
33
|
+
)
|
|
34
|
+
raise ValueError(message)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class NameSubstitutor:
|
|
39
|
+
project_name: str
|
|
40
|
+
path: Path
|
|
41
|
+
current_project_name: str = ""
|
|
42
|
+
custom_template_package_name: str = "python-package-qtemplate"
|
|
43
|
+
|
|
44
|
+
def __post_init__(self) -> None:
|
|
45
|
+
self.new_project = Project(self.project_name, self.path)
|
|
46
|
+
if not self.current_project_name:
|
|
47
|
+
self.current_project_name = self.extract_current_project_name()
|
|
48
|
+
self.template_project = Project(self.current_project_name, self.path)
|
|
49
|
+
self.substitutions = {
|
|
50
|
+
self.custom_template_package_name: self.template_project.package_slug,
|
|
51
|
+
self.template_project.name: self.new_project.name,
|
|
52
|
+
self.template_project.package_slug: self.new_project.package_slug,
|
|
53
|
+
self.template_project.package_name: self.new_project.package_name,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
def extract_current_project_name(self) -> str:
|
|
57
|
+
package_slug = extract_package_slug(self.path)
|
|
58
|
+
if package_slug == self.custom_template_package_name:
|
|
59
|
+
package_name = extract_package_name(self.path)
|
|
60
|
+
package_slug = slugify(package_name, separator="-")
|
|
61
|
+
return package_slug
|
|
62
|
+
|
|
63
|
+
def run(self) -> None:
|
|
64
|
+
for path in self.generate_paths_to_substitute():
|
|
65
|
+
self.apply_substitutions(path)
|
|
66
|
+
|
|
67
|
+
def apply_substitutions(self, path: Path) -> None:
|
|
68
|
+
content = path.text
|
|
69
|
+
if any(to_replace in content for to_replace in self.substitutions):
|
|
70
|
+
for original, replacement in self.substitutions.items():
|
|
71
|
+
content = content.replace(original, replacement)
|
|
72
|
+
path.text = content
|
|
73
|
+
|
|
74
|
+
def generate_paths_to_substitute(self) -> Iterator[Path]:
|
|
75
|
+
workflows_folder = self.path / ".github" / "workflows"
|
|
76
|
+
for path in self.generate_project_files():
|
|
77
|
+
# Modifying workflow files requires additional permissions.
|
|
78
|
+
# Therefore, we don't do substitute those
|
|
79
|
+
is_workflow = path.is_relative_to(workflows_folder)
|
|
80
|
+
is_file = path.is_file()
|
|
81
|
+
if not is_workflow and is_file:
|
|
82
|
+
try:
|
|
83
|
+
path.text
|
|
84
|
+
has_text = True
|
|
85
|
+
except UnicodeDecodeError:
|
|
86
|
+
has_text = False
|
|
87
|
+
if has_text:
|
|
88
|
+
yield path
|
|
89
|
+
self.rename(path)
|
|
90
|
+
|
|
91
|
+
def rename(self, path: Path) -> None:
|
|
92
|
+
if any(name == self.template_project.package_name for name in path.parts):
|
|
93
|
+
renamed_path_str = str(path).replace(
|
|
94
|
+
self.template_project.package_name,
|
|
95
|
+
self.new_project.package_name,
|
|
96
|
+
)
|
|
97
|
+
renamed_path = Path(renamed_path_str)
|
|
98
|
+
path.rename(renamed_path)
|
|
99
|
+
|
|
100
|
+
def generate_project_files(self) -> Iterator[Path]:
|
|
101
|
+
command = ("git", "ls-tree", "-r", "HEAD", "--name-only")
|
|
102
|
+
relative_paths = cli.lines(command, cwd=self.path)
|
|
103
|
+
for path in relative_paths:
|
|
104
|
+
yield self.path / path
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def substitute_template_name(
|
|
108
|
+
project_name: str = "",
|
|
109
|
+
path_str: str = "",
|
|
110
|
+
current_project_name: str = "",
|
|
111
|
+
) -> None:
|
|
112
|
+
# TODO: use create instance from cli args from package-utils
|
|
113
|
+
path = Path(path_str) if path_str else Path.cwd()
|
|
114
|
+
NameSubstitutor(project_name, path, current_project_name=current_project_name).run()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from concurrent.futures import ThreadPoolExecutor
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
import github.Auth
|
|
5
|
+
from github import Github, UnknownObjectException
|
|
6
|
+
from github.Repository import Repository
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class TemplateSyncTriggerer:
|
|
11
|
+
token: str
|
|
12
|
+
workflow_name: str = "sync-template.yml"
|
|
13
|
+
max_workers: int = 10
|
|
14
|
+
|
|
15
|
+
def __post_init__(self) -> None:
|
|
16
|
+
auth = github.Auth.Token(self.token)
|
|
17
|
+
self.client = Github(auth=auth)
|
|
18
|
+
|
|
19
|
+
def run(self) -> None:
|
|
20
|
+
paginated_repos = self.client.get_user().get_repos(type="owner")
|
|
21
|
+
repos = list(paginated_repos)
|
|
22
|
+
with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
|
|
23
|
+
executor.map(self.trigger_if_possible, repos)
|
|
24
|
+
|
|
25
|
+
def trigger_if_possible(self, repo: Repository) -> None:
|
|
26
|
+
try:
|
|
27
|
+
workflow = repo.get_workflow(self.workflow_name)
|
|
28
|
+
except UnknownObjectException:
|
|
29
|
+
workflow = None
|
|
30
|
+
|
|
31
|
+
if workflow is not None:
|
|
32
|
+
workflow.create_dispatch("main")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def trigger_template_sync(token: str) -> None:
|
|
36
|
+
TemplateSyncTriggerer(token).run()
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .path import Path
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TypeVar
|
|
4
|
+
|
|
5
|
+
import plib
|
|
6
|
+
from simple_classproperty import classproperty
|
|
7
|
+
|
|
8
|
+
T = TypeVar("T", bound="Path")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Path(plib.Path): # type: ignore # TODO: remove after superpathlib fix
|
|
12
|
+
@classproperty
|
|
13
|
+
def readme(cls: type[T]) -> T: # type: ignore
|
|
14
|
+
return cls("README.md")
|
|
File without changes
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import typing
|
|
3
|
+
from collections.abc import Iterator
|
|
4
|
+
|
|
5
|
+
import cli
|
|
6
|
+
|
|
7
|
+
from package_dev_tools.utils.package import extract_package_slug
|
|
8
|
+
|
|
9
|
+
from ..models import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def check_coverage(verify_all_files_tested: bool = True) -> None:
|
|
13
|
+
generate_coverage_results()
|
|
14
|
+
if verify_all_files_tested:
|
|
15
|
+
verify_all_python_files_tested()
|
|
16
|
+
|
|
17
|
+
coverage_percentage = cli.get("coverage report --format total")
|
|
18
|
+
coverage_percentage = typing.cast(str, coverage_percentage)
|
|
19
|
+
coverage_percentage_has_changed = update_coverage_shield(coverage_percentage)
|
|
20
|
+
if coverage_percentage_has_changed:
|
|
21
|
+
print(f"Updated test coverage: {coverage_percentage}%")
|
|
22
|
+
cli.get("coverage html")
|
|
23
|
+
exit_code = 1 if coverage_percentage_has_changed else 0
|
|
24
|
+
sys.exit(exit_code)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def update_coverage_shield(coverage_percentage: float | str) -> bool:
|
|
28
|
+
if isinstance(coverage_percentage, str):
|
|
29
|
+
coverage_percentage = float(coverage_percentage)
|
|
30
|
+
coverage_percentage_int = round(coverage_percentage)
|
|
31
|
+
markdown_line_start = ""
|
|
35
|
+
current_markdown_lines = Path.readme.lines
|
|
36
|
+
no_badge = not any(markdown_line_start in line for line in current_markdown_lines)
|
|
37
|
+
if no_badge:
|
|
38
|
+
raise Exception("README has no coverage badge yet.")
|
|
39
|
+
converage_percentage_has_changed = markdown_line not in current_markdown_lines
|
|
40
|
+
lines = (
|
|
41
|
+
markdown_line if line.startswith(markdown_line_start) else line
|
|
42
|
+
for line in current_markdown_lines
|
|
43
|
+
)
|
|
44
|
+
lines_with_empty_lines = *lines, ""
|
|
45
|
+
Path.readme.text = "\n".join(lines_with_empty_lines)
|
|
46
|
+
return converage_percentage_has_changed
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def verify_all_python_files_tested() -> None:
|
|
50
|
+
python_files = set(generate_python_files())
|
|
51
|
+
coverage_lines = cli.lines("coverage report")
|
|
52
|
+
covered_files = set(line.split()[0] for line in coverage_lines[2:-2])
|
|
53
|
+
not_covered_files = python_files - covered_files
|
|
54
|
+
if not_covered_files:
|
|
55
|
+
message_parts = (
|
|
56
|
+
"The following files are not covered by tests:",
|
|
57
|
+
*not_covered_files,
|
|
58
|
+
)
|
|
59
|
+
message = "\n\t".join(message_parts)
|
|
60
|
+
raise Exception(message)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def generate_python_files() -> Iterator[str]:
|
|
64
|
+
project_folder = Path.cwd()
|
|
65
|
+
python_files = project_folder.rglob("*.py")
|
|
66
|
+
for path in python_files:
|
|
67
|
+
relative_path = path.relative_to(project_folder)
|
|
68
|
+
if relative_path.parts[0] != "build":
|
|
69
|
+
yield str(relative_path)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def generate_coverage_results() -> None:
|
|
73
|
+
coverage_results_path = Path(".coverage")
|
|
74
|
+
package_slug = extract_package_slug()
|
|
75
|
+
try:
|
|
76
|
+
package_info = cli.get("pip show", package_slug)
|
|
77
|
+
except cli.CalledProcessError:
|
|
78
|
+
is_installed_non_editable = False
|
|
79
|
+
else:
|
|
80
|
+
is_installed_non_editable = "Editable project location: " not in package_info
|
|
81
|
+
if is_installed_non_editable:
|
|
82
|
+
cli.run("pip uninstall -y", package_slug)
|
|
83
|
+
coverage_results_path.unlink(missing_ok=True)
|
|
84
|
+
if not Path(".coverage").exists():
|
|
85
|
+
cli.run("coverage run")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .utils import extract_package_name, extract_package_slug
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import tomllib
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from plib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def extract_package_name(path: Path | None = None) -> str:
|
|
8
|
+
info = extract_pyproject_info(path)
|
|
9
|
+
package_data = info["tool"]["setuptools"]["package-data"]
|
|
10
|
+
project_name = next(iter(package_data))
|
|
11
|
+
return project_name
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def extract_package_slug(path: Path | None = None) -> str:
|
|
15
|
+
info = extract_pyproject_info(path)
|
|
16
|
+
return info["project"]["name"]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def extract_pyproject_info(path: Path | None) -> dict[str, Any]:
|
|
20
|
+
if path is None:
|
|
21
|
+
path = Path.cwd()
|
|
22
|
+
info_path = path / "pyproject.toml"
|
|
23
|
+
return tomllib.loads(info_path.text)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .utils import clear_cli_args, set_cli_args
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from _pytest.monkeypatch import MonkeyPatch
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def clear_cli_args(monkeypatch: MonkeyPatch) -> None:
|
|
8
|
+
set_cli_args(monkeypatch)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def set_cli_args(monkeypatch: MonkeyPatch, *args: Any) -> None:
|
|
12
|
+
str_args = (str(arg) for arg in args)
|
|
13
|
+
sys_args = ["test_create_instance", *str_args]
|
|
14
|
+
monkeypatch.setattr(sys, "argv", sys_args)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# don't bump/check bump in GitHub actions
|
|
4
|
+
if [ "$(git branch --show-current)" = "main" ]; then
|
|
5
|
+
if [ "$GITHUB_ACTIONS" != "true" ]; then
|
|
6
|
+
if ! git diff --staged pyproject.toml | grep -q version; then
|
|
7
|
+
bump2version --config-file .bumpversion.cfg patch
|
|
8
|
+
fi
|
|
9
|
+
fi
|
|
10
|
+
fi
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Quinten Roets
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: package-dev-tools
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Python package
|
|
5
|
+
Author-email: Quinten Roets <qdr2104@columbia.edu>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Source Code, https://github.com/quintenroets/package-dev-tools
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: pygithub >=2.1
|
|
12
|
+
Requires-Dist: python-slugify >=8.0
|
|
13
|
+
Requires-Dist: simple-classproperty >=4.0
|
|
14
|
+
Requires-Dist: superpathlib >=1.3
|
|
15
|
+
Requires-Dist: typer >=0.9
|
|
16
|
+
Requires-Dist: quinten-cli >=1.1
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: build ; extra == 'dev'
|
|
19
|
+
Requires-Dist: bump2version ; extra == 'dev'
|
|
20
|
+
Requires-Dist: coverage ; extra == 'dev'
|
|
21
|
+
Requires-Dist: hypothesis ; extra == 'dev'
|
|
22
|
+
Requires-Dist: pre-commit ; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest ; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-mypy-plugins ; extra == 'dev'
|
|
25
|
+
Requires-Dist: package-dev-tools ; extra == 'dev'
|
|
26
|
+
|
|
27
|
+
# Package Dev Tools
|
|
28
|
+
[](https://badge.fury.io/py/package-dev-tools)
|
|
29
|
+

|
|
30
|
+
## Usage
|
|
31
|
+
* Use [actions](https://github.com/quintenroets/package-dev-tools/tree/main/actions) in .github/workflows
|
|
32
|
+
* Use [pre-commit hooks](https://github.com/quintenroets/package-dev-tools/tree/main/.pre-commit-hooks.yaml) in .pre-commit-config.yaml
|
|
33
|
+
## Installation
|
|
34
|
+
```shell
|
|
35
|
+
pip install package-dev-tools
|
|
36
|
+
```
|
|
37
|
+
make sure to use Python 3.10+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package_dev_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
package_dev_tools/py.typed,sha256=4W8VliAYUP1KY2gLJ_YDy2TmcXYVm-PY7XikQD_bFwA,2
|
|
3
|
+
package_dev_tools/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
package_dev_tools/actions/cleanup_readme.py,sha256=zXQYuH2ozySGYG0zjzT-d-47njcYQCbC38Cqbkjf0FU,275
|
|
5
|
+
package_dev_tools/actions/substitute_template_name.py,sha256=v1dXBkgeKOPMOUkUnrgUlzkR9j85YXiJm_jQIWP48yI,4312
|
|
6
|
+
package_dev_tools/actions/trigger_template_sync.py,sha256=TWJvzc33sBBk26djwO3WgI3uopcHm3yIFHs0ziE1A4Y,1088
|
|
7
|
+
package_dev_tools/interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
package_dev_tools/interfaces/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
package_dev_tools/interfaces/cli/check_coverage.py,sha256=FEW2owlotguGQQ3dNSMRdV7W4L464kZPFIl8rbln_to,144
|
|
10
|
+
package_dev_tools/interfaces/cli/cleanup_readme.py,sha256=u4G9sOGbynNwKC-9TlNjMONiZEewxYfrluz8aORCFZc,141
|
|
11
|
+
package_dev_tools/interfaces/cli/substitute_template_name.py,sha256=r3b1ApRg1--Vvw0C0DpDUO7Emuj5lKmuOzO8jyO2URw,171
|
|
12
|
+
package_dev_tools/interfaces/cli/trigger_template_sync.py,sha256=m4qM9EcAVVOSlp0HiRIDL-uQp6N5wlJGlmSTOTyFtnE,162
|
|
13
|
+
package_dev_tools/models/__init__.py,sha256=1OeLZ6FZ5gAjlerAjc69Vx0AqWLSx6OSqNCpuzkCZQg,23
|
|
14
|
+
package_dev_tools/models/path.py,sha256=S5QYiFx18oYG0MYH75axKTtoH4_Fr72zna5GxQ9ljtw,336
|
|
15
|
+
package_dev_tools/pre_commit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
package_dev_tools/pre_commit/check_coverage.py,sha256=0HBFRGzeSYQiG47uv5hFymLXl8UIEdDKKFjkrpBLWYE,3198
|
|
17
|
+
package_dev_tools/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
package_dev_tools/utils/package/__init__.py,sha256=qDQe6KPiKE-5tUo57zVgTCIu3ej-4_LHmeDQWDMJGyc,62
|
|
19
|
+
package_dev_tools/utils/package/utils.py,sha256=iMWZs4EtjfAQAhFE1vmdGugl-S9AC9v5GkX8_phOZF8,623
|
|
20
|
+
package_dev_tools/utils/tests/__init__.py,sha256=2PBvBgS2em5pX-VCEhQ3LWJbQDiKl4a3FkpYi8nnp48,48
|
|
21
|
+
package_dev_tools/utils/tests/utils.py,sha256=LExKTxz-cMxOGjW7UmVK5VWYmYnc0ZXd5f4suI5X10U,371
|
|
22
|
+
package_dev_tools-0.1.1.data/scripts/check-version,sha256=Xwnoo_HQJAOqRlsL5CypDQQDa0iOm0MVDoezTLsUg0c,314
|
|
23
|
+
package_dev_tools-0.1.1.data/scripts/cleanup-workflows,sha256=Sn81o-jvTK-r1RR2q-J9DCA8W7NxcQsG_ddjLMLvLrg,104
|
|
24
|
+
package_dev_tools-0.1.1.dist-info/LICENSE,sha256=ENpNaBSvIV7ifD7iNz_-lBhImbiYowqPzBc5V5R8IhM,1070
|
|
25
|
+
package_dev_tools-0.1.1.dist-info/METADATA,sha256=EhD9KtSSDfHv-A3M2R6DAXpS_GCXXYjzYDCkeAQc-oc,1425
|
|
26
|
+
package_dev_tools-0.1.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
27
|
+
package_dev_tools-0.1.1.dist-info/entry_points.txt,sha256=FXlki7scg9b9vz0VKu3Xas23c0v_0daF8FoVZVA7rBU,353
|
|
28
|
+
package_dev_tools-0.1.1.dist-info/top_level.txt,sha256=PqhxIcDJGvTSOvYGWFahqZFabfDh2COOD1aRPS_7WOg,18
|
|
29
|
+
package_dev_tools-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
check-coverage = package_dev_tools.interfaces.cli.check_coverage:entry_point
|
|
3
|
+
cleanup-readme = package_dev_tools.interfaces.cli.cleanup_readme:entry_point
|
|
4
|
+
substitute-template-name = package_dev_tools.interfaces.cli.substitute_template_name:entry_point
|
|
5
|
+
trigger-template-sync = package_dev_tools.interfaces.cli.cleanup_readme:entry_point
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
package_dev_tools
|