quickpub 0.5.0__tar.gz → 0.8.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.
- quickpub-0.8.0/LICENSE +21 -0
- quickpub-0.8.0/MANIFEST.in +1 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/PKG-INFO +33 -2
- quickpub-0.8.0/README.md +31 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/pyproject.toml +6 -4
- quickpub-0.8.0/quickpub/__init__.py +3 -0
- quickpub-0.8.0/quickpub/__main__.py +102 -0
- quickpub-0.8.0/quickpub/custom_types.py +12 -0
- quickpub-0.8.0/quickpub/enforcers.py +58 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/quickpub/files.py +18 -5
- quickpub-0.5.0/quickpub/publish.py → quickpub-0.8.0/quickpub/functions.py +34 -14
- quickpub-0.8.0/quickpub/proxy.py +26 -0
- quickpub-0.8.0/quickpub/py.typed +0 -0
- quickpub-0.8.0/quickpub/runnables/__init__.py +2 -0
- quickpub-0.8.0/quickpub/runnables/common_check.py +57 -0
- quickpub-0.8.0/quickpub/runnables/configurable.py +20 -0
- quickpub-0.8.0/quickpub/runnables/has_optional_executable.py +27 -0
- quickpub-0.8.0/quickpub/runnables/implementations/__init__.py +4 -0
- quickpub-0.8.0/quickpub/runnables/implementations/mypy.py +29 -0
- quickpub-0.8.0/quickpub/runnables/implementations/pylint.py +30 -0
- quickpub-0.8.0/quickpub/runnables/implementations/pytest.py +1 -0
- quickpub-0.8.0/quickpub/runnables/implementations/unittest.py +50 -0
- quickpub-0.8.0/quickpub/runnables/runnable.py +11 -0
- quickpub-0.8.0/quickpub/structures/__init__.py +3 -0
- quickpub-0.8.0/quickpub/structures/additional_configuration.py +13 -0
- quickpub-0.8.0/quickpub/structures/bound.py +30 -0
- quickpub-0.8.0/quickpub/structures/version.py +27 -0
- quickpub-0.8.0/quickpub/validators.py +46 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/quickpub.egg-info/PKG-INFO +33 -2
- quickpub-0.8.0/quickpub.egg-info/SOURCES.txt +34 -0
- quickpub-0.5.0/README.md +0 -1
- quickpub-0.5.0/quickpub/__init__.py +0 -6
- quickpub-0.5.0/quickpub/__main__.py +0 -67
- quickpub-0.5.0/quickpub/proxy.py +0 -11
- quickpub-0.5.0/quickpub/structures.py +0 -28
- quickpub-0.5.0/quickpub.egg-info/SOURCES.txt +0 -15
- {quickpub-0.5.0 → quickpub-0.8.0}/quickpub/classifiers.py +0 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/quickpub.egg-info/dependency_links.txt +0 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/quickpub.egg-info/requires.txt +0 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/quickpub.egg-info/top_level.txt +0 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/setup.cfg +0 -0
- {quickpub-0.5.0 → quickpub-0.8.0}/setup.py +0 -0
quickpub-0.8.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 danielnachumdev
|
|
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 @@
|
|
|
1
|
+
recursive-include quickpub *.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: quickpub
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: A python package to quickly configure and publish a new package
|
|
5
5
|
Author-email: danielnachumdev <danielnachumdev@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -30,7 +30,38 @@ Classifier: Development Status :: 3 - Alpha
|
|
|
30
30
|
Classifier: Intended Audience :: Developers
|
|
31
31
|
Classifier: Programming Language :: Python :: 3
|
|
32
32
|
Classifier: Operating System :: Microsoft :: Windows
|
|
33
|
-
Requires-Python: >=3.
|
|
33
|
+
Requires-Python: >=3.9.19
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
35
36
|
|
|
36
37
|
# quickpub
|
|
38
|
+
|
|
39
|
+
Example usage of how this package was published
|
|
40
|
+
```python
|
|
41
|
+
from quickpub import publish, AdditionalConfiguration, MypyRunner, PylintRunner, UnittestRunner
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def main() -> None:
|
|
45
|
+
publish(
|
|
46
|
+
name="quickpub",
|
|
47
|
+
version="0.8.0",
|
|
48
|
+
author="danielnachumdev",
|
|
49
|
+
author_email="danielnachumdev@gmail.com",
|
|
50
|
+
description="A python package to quickly configure and publish a new package",
|
|
51
|
+
homepage="https://github.com/danielnachumdev/quickpub",
|
|
52
|
+
dependencies=["twine", "danielutils"],
|
|
53
|
+
min_python="3.9.19",
|
|
54
|
+
config=AdditionalConfiguration(
|
|
55
|
+
runners=[
|
|
56
|
+
MypyRunner(),
|
|
57
|
+
PylintRunner(),
|
|
58
|
+
UnittestRunner(),
|
|
59
|
+
]
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == '__main__':
|
|
65
|
+
main()
|
|
66
|
+
|
|
67
|
+
```
|
quickpub-0.8.0/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# quickpub
|
|
2
|
+
|
|
3
|
+
Example usage of how this package was published
|
|
4
|
+
```python
|
|
5
|
+
from quickpub import publish, AdditionalConfiguration, MypyRunner, PylintRunner, UnittestRunner
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
publish(
|
|
10
|
+
name="quickpub",
|
|
11
|
+
version="0.8.0",
|
|
12
|
+
author="danielnachumdev",
|
|
13
|
+
author_email="danielnachumdev@gmail.com",
|
|
14
|
+
description="A python package to quickly configure and publish a new package",
|
|
15
|
+
homepage="https://github.com/danielnachumdev/quickpub",
|
|
16
|
+
dependencies=["twine", "danielutils"],
|
|
17
|
+
min_python="3.9.19",
|
|
18
|
+
config=AdditionalConfiguration(
|
|
19
|
+
runners=[
|
|
20
|
+
MypyRunner(),
|
|
21
|
+
PylintRunner(),
|
|
22
|
+
UnittestRunner(),
|
|
23
|
+
]
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if __name__ == '__main__':
|
|
29
|
+
main()
|
|
30
|
+
|
|
31
|
+
```
|
|
@@ -4,16 +4,16 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "quickpub"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.8.0"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
|
|
10
10
|
]
|
|
11
11
|
dependencies = ['twine', 'danielutils']
|
|
12
12
|
keywords = []
|
|
13
|
-
license = { "file" = "
|
|
13
|
+
license = { "file" = "./LICENSE" }
|
|
14
14
|
description = "A python package to quickly configure and publish a new package"
|
|
15
|
-
readme = "README.md"
|
|
16
|
-
requires-python = ">=3.
|
|
15
|
+
readme = {file = "./README.md", content-type = "text/markdown"}
|
|
16
|
+
requires-python = ">=3.9.19"
|
|
17
17
|
classifiers = [
|
|
18
18
|
"Development Status :: 3 - Alpha",
|
|
19
19
|
"Intended Audience :: Developers",
|
|
@@ -23,6 +23,8 @@ classifiers = [
|
|
|
23
23
|
|
|
24
24
|
[tool.setuptools]
|
|
25
25
|
packages = ["quickpub"]
|
|
26
|
+
[tool.setuptools.package-data]
|
|
27
|
+
"quickpub" = ["py.typed"]
|
|
26
28
|
|
|
27
29
|
[project.urls]
|
|
28
30
|
"Homepage" = "https://github.com/danielnachumdev/quickpub"
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from typing import Optional, Union
|
|
2
|
+
from danielutils import warning, file_exists
|
|
3
|
+
from .validators import validate_version, validate_python_version, validate_keywords, validate_dependencies, \
|
|
4
|
+
validate_source
|
|
5
|
+
from .functions import build, upload, commit, metrics
|
|
6
|
+
from .structures import Version, AdditionalConfiguration
|
|
7
|
+
from .files import create_toml, create_setup, create_manifest
|
|
8
|
+
from .classifiers import *
|
|
9
|
+
from .enforcers import enforce_local_correct_version, enforce_pypirc_exists, exit_if, enforce_remote_correct_version
|
|
10
|
+
from .custom_types import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def publish(
|
|
14
|
+
*,
|
|
15
|
+
name: str,
|
|
16
|
+
author: str,
|
|
17
|
+
author_email: str,
|
|
18
|
+
description: str,
|
|
19
|
+
homepage: str,
|
|
20
|
+
src: Optional[Path] = None,
|
|
21
|
+
version: Optional[Union[Version, str]] = None,
|
|
22
|
+
readme: Path = "./README.md",
|
|
23
|
+
license: Path = "./LICENSE",
|
|
24
|
+
|
|
25
|
+
min_python: Optional[Union[Version, str]] = None,
|
|
26
|
+
|
|
27
|
+
keywords: Optional[list[str]] = None,
|
|
28
|
+
dependencies: Optional[list[str]] = None,
|
|
29
|
+
config: Optional[AdditionalConfiguration] = None
|
|
30
|
+
) -> None:
|
|
31
|
+
"""The main function of this package. will do all the heavy lifting in order for you to publish your package.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
name (str): The name of the package
|
|
35
|
+
author (str): The name of the author
|
|
36
|
+
author_email (str): The email of the author
|
|
37
|
+
description (str): A short description for the package
|
|
38
|
+
homepage (str): The homepage for the package. URL to the github repo is a good option.
|
|
39
|
+
src (Optional[Path], optional): The path to the source code of the package. if None defaults to CWD/<name>
|
|
40
|
+
version (Optional[Union[Version, str]], optional): The version to create the new distribution. if None defaults to 0.0.1
|
|
41
|
+
readme (Path, optional): The path to the readme file. Defaults to "./README.md".
|
|
42
|
+
license (Path, optional): The path to the license file . Defaults to "./LICENSE".
|
|
43
|
+
min_python (Optional[Union[Version, str]], optional): The minimum version of python required for this package to run. Defaults to the version of python running this script.
|
|
44
|
+
keywords (Optional[list[str]], optional): A list of keywords to describe areas of interests of this package. Defaults to None.
|
|
45
|
+
dependencies (Optional[list[str]], optional): A list of the dependencies for this package. Defaults to None.
|
|
46
|
+
config (Optional[Config], optional): reserved for future use. Defaults to None.
|
|
47
|
+
"""
|
|
48
|
+
enforce_pypirc_exists()
|
|
49
|
+
src = validate_source(name, src)
|
|
50
|
+
if src != f"./{name}":
|
|
51
|
+
warning(
|
|
52
|
+
"The source folder's name is different from the package's name. this may not be currently supported correctly")
|
|
53
|
+
exit_if(not file_exists(readme), f"Could not find readme file at {readme}")
|
|
54
|
+
exit_if(not file_exists(license),
|
|
55
|
+
f"Could not find license file at {license}")
|
|
56
|
+
version = validate_version(version)
|
|
57
|
+
enforce_local_correct_version(name, version)
|
|
58
|
+
min_python = validate_python_version(min_python) # type:ignore
|
|
59
|
+
keywords = validate_keywords(keywords)
|
|
60
|
+
dependencies = validate_dependencies(dependencies)
|
|
61
|
+
enforce_remote_correct_version(name, version)
|
|
62
|
+
|
|
63
|
+
if config is not None:
|
|
64
|
+
if config.runners is not None:
|
|
65
|
+
for runner in config.runners:
|
|
66
|
+
runner.run(src)
|
|
67
|
+
|
|
68
|
+
create_setup()
|
|
69
|
+
create_toml(
|
|
70
|
+
name=name,
|
|
71
|
+
src=src,
|
|
72
|
+
readme=readme,
|
|
73
|
+
license=license,
|
|
74
|
+
version=version,
|
|
75
|
+
author=author,
|
|
76
|
+
author_email=author_email,
|
|
77
|
+
description=description,
|
|
78
|
+
homepage=homepage,
|
|
79
|
+
keywords=keywords,
|
|
80
|
+
dependencies=dependencies,
|
|
81
|
+
classifiers=[
|
|
82
|
+
DevelopmentStatusClassifier.Alpha,
|
|
83
|
+
IntendedAudienceClassifier.Developers,
|
|
84
|
+
ProgrammingLanguageClassifier.Python3,
|
|
85
|
+
OperatingSystemClassifier.MicrosoftWindows
|
|
86
|
+
],
|
|
87
|
+
min_python=min_python
|
|
88
|
+
)
|
|
89
|
+
create_manifest(name=name)
|
|
90
|
+
|
|
91
|
+
build()
|
|
92
|
+
upload(
|
|
93
|
+
name=name,
|
|
94
|
+
version=version
|
|
95
|
+
)
|
|
96
|
+
commit(
|
|
97
|
+
version=version
|
|
98
|
+
)
|
|
99
|
+
metrics()
|
|
100
|
+
|
|
101
|
+
# if __name__ == '__main__':
|
|
102
|
+
# publish()
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from typing import Union, Callable
|
|
3
|
+
|
|
4
|
+
import requests
|
|
5
|
+
# from bs4 import BeautifulSoup
|
|
6
|
+
from danielutils import directory_exists, get_files, error, file_exists
|
|
7
|
+
from .structures import Version
|
|
8
|
+
from .proxy import get
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def exit_if(predicate: Union[bool, Callable[[], bool]], msg: str) -> None:
|
|
12
|
+
if (isinstance(predicate, bool) and predicate) or (callable(predicate) and predicate()):
|
|
13
|
+
error(msg)
|
|
14
|
+
sys.exit(1)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def enforce_local_correct_version(name: str, version: Version) -> None:
|
|
18
|
+
if directory_exists("./dist"):
|
|
19
|
+
max_version = Version(0, 0, 0)
|
|
20
|
+
for d in get_files("./dist"):
|
|
21
|
+
d = d.removeprefix(f"{name}-").removesuffix(".tar.gz")
|
|
22
|
+
v = Version.from_str(d)
|
|
23
|
+
max_version = max(max_version, v)
|
|
24
|
+
exit_if(
|
|
25
|
+
version <= max_version,
|
|
26
|
+
f"Specified version is '{version}' but (locally available) latest existing is '{max_version}'"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def enforce_remote_correct_version(name: str, version: Version) -> None:
|
|
31
|
+
pass
|
|
32
|
+
# url = f"https://pypi.org/project/{name}/#history"
|
|
33
|
+
# headers = {
|
|
34
|
+
# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
|
|
35
|
+
# }
|
|
36
|
+
# response = requests.get(url, headers=headers)
|
|
37
|
+
# if response.status_code != 200:
|
|
38
|
+
# return
|
|
39
|
+
# soup = BeautifulSoup(response.text, "html.parser")
|
|
40
|
+
# divs = soup.find_all("div", class_="release")
|
|
41
|
+
# versions = []
|
|
42
|
+
# for div in divs:
|
|
43
|
+
# ver = div.find("p", class_="release__version").text.strip()
|
|
44
|
+
# versions.append(ver)
|
|
45
|
+
# pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def enforce_pypirc_exists() -> None:
|
|
49
|
+
exit_if(
|
|
50
|
+
not file_exists("./.pypirc"),
|
|
51
|
+
"No .pypirc file found"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
__all__ = [
|
|
56
|
+
"enforce_local_correct_version",
|
|
57
|
+
"enforce_pypirc_exists"
|
|
58
|
+
]
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
1
|
+
from .custom_types import Path
|
|
3
2
|
from .classifiers import Classifier
|
|
4
3
|
from .structures import Version
|
|
4
|
+
from danielutils import get_files
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def create_toml(
|
|
8
8
|
*,
|
|
9
9
|
name: str,
|
|
10
|
+
src: Path,
|
|
11
|
+
readme: Path,
|
|
12
|
+
license: Path,
|
|
10
13
|
version: Version,
|
|
11
14
|
author: str,
|
|
12
15
|
author_email: str,
|
|
@@ -20,6 +23,13 @@ def create_toml(
|
|
|
20
23
|
classifiers_string = ",\n\t".join([f"\"{str(c)}\"" for c in classifiers])
|
|
21
24
|
if len(classifiers_string) > 0:
|
|
22
25
|
classifiers_string = f"\n\t{classifiers_string}\n"
|
|
26
|
+
py_typed = ""
|
|
27
|
+
for file in get_files(src):
|
|
28
|
+
if file == "py.typed":
|
|
29
|
+
py_typed = f"""[tool.setuptools.package-data]
|
|
30
|
+
"{name}" = ["py.typed"]"""
|
|
31
|
+
break
|
|
32
|
+
|
|
23
33
|
s = f"""[build-system]
|
|
24
34
|
requires = ["setuptools>=61.0"]
|
|
25
35
|
build-backend = "setuptools.build_meta"
|
|
@@ -32,14 +42,15 @@ authors = [
|
|
|
32
42
|
]
|
|
33
43
|
dependencies = {dependencies}
|
|
34
44
|
keywords = {keywords}
|
|
35
|
-
license = {{ "file" = "
|
|
45
|
+
license = {{ "file" = "{license}" }}
|
|
36
46
|
description = "{description}"
|
|
37
|
-
readme = "
|
|
47
|
+
readme = {{file = "{readme}", content-type = "text/markdown"}}
|
|
38
48
|
requires-python = ">={min_python}"
|
|
39
49
|
classifiers = [{classifiers_string}]
|
|
40
50
|
|
|
41
51
|
[tool.setuptools]
|
|
42
52
|
packages = ["{name}"]
|
|
53
|
+
{py_typed}
|
|
43
54
|
|
|
44
55
|
[project.urls]
|
|
45
56
|
"Homepage" = "{homepage}"
|
|
@@ -52,7 +63,9 @@ packages = ["{name}"]
|
|
|
52
63
|
def create_setup() -> None:
|
|
53
64
|
with open("./setup.py", "w", encoding="utf8") as f:
|
|
54
65
|
f.write("from setuptools import setup\n\nsetup()\n")
|
|
55
|
-
|
|
66
|
+
def create_manifest(*,name:str)->None:
|
|
67
|
+
with open("./MANIFEST.in", "w", encoding="utf8") as f:
|
|
68
|
+
f.write(f"recursive-include {name} *.py")
|
|
56
69
|
|
|
57
70
|
__all__ = [
|
|
58
71
|
"create_setup",
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import sys
|
|
2
|
+
from typing import Optional, Literal
|
|
3
|
+
from danielutils import info
|
|
2
4
|
|
|
3
|
-
from .
|
|
5
|
+
from .enforcers import exit_if
|
|
4
6
|
from .structures import Version
|
|
7
|
+
import quickpub.proxy
|
|
8
|
+
|
|
9
|
+
|
|
5
10
|
|
|
6
11
|
|
|
7
12
|
def prev_main():
|
|
@@ -147,10 +152,11 @@ def build(
|
|
|
147
152
|
) -> None:
|
|
148
153
|
if verbose:
|
|
149
154
|
info("Creating new distribution...")
|
|
150
|
-
ret, stdout, stderr = cm("python", "setup.py", "sdist")
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
ret, stdout, stderr = quickpub.proxy.cm("python", "setup.py", "sdist")
|
|
156
|
+
exit_if(
|
|
157
|
+
ret != 0,
|
|
158
|
+
stderr.decode(encoding="utf8")
|
|
159
|
+
)
|
|
154
160
|
|
|
155
161
|
|
|
156
162
|
def upload(
|
|
@@ -161,10 +167,12 @@ def upload(
|
|
|
161
167
|
) -> None:
|
|
162
168
|
if verbose:
|
|
163
169
|
info("Uploading")
|
|
164
|
-
ret, stdout, stderr = cm("
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
170
|
+
ret, stdout, stderr = quickpub.proxy.cm("twine", "upload", "--config-file", ".pypirc",
|
|
171
|
+
f"dist/{name}-{version}.tar.gz")
|
|
172
|
+
exit_if(
|
|
173
|
+
ret != 0,
|
|
174
|
+
f"Failed uploading the package to pypi. Try running the following command manually:\n\ttwine upload --config-file .pypirc dist/{name}-{version}.tar.gz"
|
|
175
|
+
)
|
|
168
176
|
|
|
169
177
|
|
|
170
178
|
def commit(
|
|
@@ -175,16 +183,28 @@ def commit(
|
|
|
175
183
|
if verbose:
|
|
176
184
|
info("Git")
|
|
177
185
|
info("\tStaging")
|
|
178
|
-
cm("git add .")
|
|
186
|
+
ret, stdout, stderr = quickpub.proxy.cm("git add .")
|
|
187
|
+
exit_if(
|
|
188
|
+
ret != 0,
|
|
189
|
+
stderr.decode(encoding="utf8")
|
|
190
|
+
)
|
|
179
191
|
if verbose:
|
|
180
192
|
info("\tCommitting")
|
|
181
|
-
cm(f"git commit -m \"updated to version {version}\"")
|
|
193
|
+
ret, stdout, stderr = quickpub.proxy.cm(f"git commit -m \"updated to version {version}\"")
|
|
194
|
+
exit_if(
|
|
195
|
+
ret != 0,
|
|
196
|
+
stderr.decode(encoding="utf8")
|
|
197
|
+
)
|
|
182
198
|
if verbose:
|
|
183
199
|
info("\tPushing")
|
|
184
|
-
cm("git push")
|
|
200
|
+
ret, stdout, stderr = quickpub.proxy.cm("git push")
|
|
201
|
+
exit_if(
|
|
202
|
+
ret != 0,
|
|
203
|
+
stderr.decode(encoding="utf8")
|
|
204
|
+
)
|
|
185
205
|
|
|
186
206
|
|
|
187
|
-
def metrics():
|
|
207
|
+
def metrics(testing_client: Optional[Literal["pytest", "unitest"]] = None):
|
|
188
208
|
pass
|
|
189
209
|
|
|
190
210
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import danielutils
|
|
2
|
+
import requests
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# need it like this for the testing
|
|
6
|
+
def cm(*args, **kwargs) -> tuple[int, bytes, bytes]:
|
|
7
|
+
return danielutils.cm(*args, **kwargs)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get(*args, **kwargs):
|
|
11
|
+
return requests.get(*args, **kwargs)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def add_verbose_keyword(func):
|
|
15
|
+
def wrapper(*args, verbose: bool = False, **kwargs):
|
|
16
|
+
if verbose:
|
|
17
|
+
return func(*args, **kwargs)
|
|
18
|
+
|
|
19
|
+
return wrapper
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"cm",
|
|
24
|
+
"get",
|
|
25
|
+
'add_verbose_keyword'
|
|
26
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from abc import abstractmethod
|
|
3
|
+
from typing import Optional, Union
|
|
4
|
+
|
|
5
|
+
from danielutils import file_exists, cm, info, get_current_working_directory, set_current_working_directory
|
|
6
|
+
|
|
7
|
+
from .has_optional_executable import HasOptionalExecutable
|
|
8
|
+
from .runnable import Runnable
|
|
9
|
+
from .configurable import Configurable
|
|
10
|
+
from ..structures import Bound
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class CommonCheck(Runnable, Configurable, HasOptionalExecutable):
|
|
14
|
+
|
|
15
|
+
def __init__(self, name: str, bound: Union[str, Bound], target: Optional[str] = None,
|
|
16
|
+
configuration_path: Optional[str] = None,
|
|
17
|
+
executable_path: Optional[str] = None) -> None:
|
|
18
|
+
Configurable.__init__(self, configuration_path)
|
|
19
|
+
HasOptionalExecutable.__init__(self, name, executable_path)
|
|
20
|
+
self.bound: Bound = bound if isinstance(bound, Bound) else Bound.from_string(bound)
|
|
21
|
+
self.target = target
|
|
22
|
+
|
|
23
|
+
def _build_command(self, target: str) -> str:
|
|
24
|
+
command: str = self.get_executable()
|
|
25
|
+
if self.has_config:
|
|
26
|
+
command += f" --rcfile {self.config_path}"
|
|
27
|
+
command += f" {target}"
|
|
28
|
+
return command
|
|
29
|
+
|
|
30
|
+
@abstractmethod
|
|
31
|
+
def _pre_command(self):
|
|
32
|
+
...
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def _post_command(self):
|
|
36
|
+
...
|
|
37
|
+
|
|
38
|
+
def run(self, target: str, *_) -> None:
|
|
39
|
+
command = self._build_command(target)
|
|
40
|
+
info(f"Running {self.name}")
|
|
41
|
+
self._pre_command()
|
|
42
|
+
try:
|
|
43
|
+
ret, out, err = cm(command)
|
|
44
|
+
score = self._calculate_score(ret, b"".join([out, err]).decode("utf-8").splitlines())
|
|
45
|
+
from ..enforcers import exit_if
|
|
46
|
+
exit_if(not self.bound.compare_against(score), f"{self.name} failed to pass it's defined bound")
|
|
47
|
+
finally:
|
|
48
|
+
self._post_command()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@abstractmethod
|
|
52
|
+
def _calculate_score(self, ret: int, command_output: list[str]) -> float: ...
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
__all__ = [
|
|
56
|
+
"CommonCheck"
|
|
57
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from danielutils import file_exists
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Configurable(ABC):
|
|
7
|
+
@property
|
|
8
|
+
def has_config(self) -> bool:
|
|
9
|
+
return self.config_path is not None
|
|
10
|
+
|
|
11
|
+
def __init__(self, config_path: Optional[str] = None):
|
|
12
|
+
self.config_path = config_path
|
|
13
|
+
if self.has_config:
|
|
14
|
+
if not file_exists(self.config_path):
|
|
15
|
+
raise FileNotFoundError(f"Can't find config file {self.config_path}")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"Configurable",
|
|
20
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import Any, Protocol, Optional
|
|
2
|
+
from danielutils import get_os, OSType, file_exists
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class HasOptionalExecutable():
|
|
6
|
+
PYTHON: str = "python" if get_os() == OSType.WINDOWS else "python3"
|
|
7
|
+
|
|
8
|
+
@property
|
|
9
|
+
def use_executable(self) -> bool:
|
|
10
|
+
return self.executable_path is not None
|
|
11
|
+
|
|
12
|
+
def __init__(self, name, executable_path: Optional[str] = None) -> None:
|
|
13
|
+
self.name = name
|
|
14
|
+
self.executable_path = executable_path
|
|
15
|
+
if self.use_executable:
|
|
16
|
+
if not file_exists(self.executable_path):
|
|
17
|
+
raise FileNotFoundError(f"Executable not found {self.executable_path}")
|
|
18
|
+
|
|
19
|
+
def get_executable(self) -> str:
|
|
20
|
+
if self.use_executable:
|
|
21
|
+
return self.executable_path
|
|
22
|
+
return f"{self.PYTHON} -m {self.name}"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
'HasOptionalExecutable',
|
|
27
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from ..common_check import CommonCheck
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MypyRunner(CommonCheck):
|
|
7
|
+
def _pre_command(self):
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
def _post_command(self):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
RATING_PATTERN: re.Pattern = re.compile(r".*?([\d\.\/]+)")
|
|
14
|
+
|
|
15
|
+
def __init__(self, configuration_path: Optional[str] = None, executable_path: Optional[str] = None) -> None:
|
|
16
|
+
CommonCheck.__init__(self, "mypy","<15", configuration_path, executable_path)
|
|
17
|
+
|
|
18
|
+
def _calculate_score(self, ret, lines: list[str]) -> float:
|
|
19
|
+
from ...enforcers import exit_if
|
|
20
|
+
rating_line = lines[-1]
|
|
21
|
+
exit_if(not (m := self.RATING_PATTERN.match(rating_line)),
|
|
22
|
+
f"Failed running MyPy, got exit code {ret}. try running manually using:\n\t{self._build_command('TARGE')}")
|
|
23
|
+
rating_string = m.group(1)
|
|
24
|
+
return float(rating_string)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
'MypyRunner',
|
|
29
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from ..common_check import CommonCheck
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PylintRunner(CommonCheck):
|
|
7
|
+
def _pre_command(self):
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
def _post_command(self):
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
def __init__(self, configuration_path: Optional[str] = None, executable_path: Optional[str] = None) -> None:
|
|
14
|
+
CommonCheck.__init__(self, "pylint",">=0.8", configuration_path, executable_path)
|
|
15
|
+
|
|
16
|
+
RATING_PATTERN: re.Pattern = re.compile(r".*?([\d\.\/]+)")
|
|
17
|
+
|
|
18
|
+
def _calculate_score(self, ret: int, lines: list[str]) -> float:
|
|
19
|
+
from ...enforcers import exit_if
|
|
20
|
+
rating_line = lines[-2]
|
|
21
|
+
exit_if(not (m := self.RATING_PATTERN.match(rating_line)),
|
|
22
|
+
f"Failed running Pylint, got exit code {ret}. try running manually using:\n\t{self._build_command('TARGET')}")
|
|
23
|
+
rating_string = m.group(1) # type:ignore
|
|
24
|
+
numerator, denominator = rating_string.split("/")
|
|
25
|
+
return float(numerator) / float(denominator)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"PylintRunner",
|
|
30
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# TODO
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import os
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from danielutils import get_current_working_directory, set_current_working_directory
|
|
5
|
+
from ..common_check import CommonCheck
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UnittestRunner(CommonCheck):
|
|
9
|
+
def _pre_command(self):
|
|
10
|
+
self._cwd = get_current_working_directory()
|
|
11
|
+
set_current_working_directory(os.path.join(self._cwd, self.target))
|
|
12
|
+
|
|
13
|
+
def _post_command(self):
|
|
14
|
+
set_current_working_directory(self._cwd)
|
|
15
|
+
|
|
16
|
+
RATING_PATTERN: re.Pattern = re.compile(r".*?([\d\.\/]+)")
|
|
17
|
+
|
|
18
|
+
def __init__(self, target: Optional[str] = "./tests") -> None:
|
|
19
|
+
CommonCheck.__init__(self, "unittest", ">=0.7", target)
|
|
20
|
+
self._cwd = ""
|
|
21
|
+
|
|
22
|
+
def _build_command(self, src: str, *args) -> str:
|
|
23
|
+
command: str = self.get_executable()
|
|
24
|
+
rel = os.path.relpath(src, self.target).removesuffix(src.lstrip("./\\"))
|
|
25
|
+
command += f" discover -s {rel}"
|
|
26
|
+
return command # f"cd {self.target}; {command}" # f"; cd {self.target}"
|
|
27
|
+
|
|
28
|
+
def _calculate_score(self, ret: int, lines: list[str]) -> float:
|
|
29
|
+
from ...enforcers import exit_if
|
|
30
|
+
num_tests_line = lines[-3]
|
|
31
|
+
num_failed_line = lines[-1] if lines[-1] != "OK" else "0"
|
|
32
|
+
try:
|
|
33
|
+
m = self.RATING_PATTERN.match(num_tests_line)
|
|
34
|
+
if not m:
|
|
35
|
+
raise AssertionError
|
|
36
|
+
num_tests = m.group(1)
|
|
37
|
+
m = self.RATING_PATTERN.match(num_failed_line)
|
|
38
|
+
if not m:
|
|
39
|
+
raise AssertionError
|
|
40
|
+
num_failed = m.group(1)
|
|
41
|
+
|
|
42
|
+
return 1.0 - (float(num_failed) / float(num_tests))
|
|
43
|
+
except:
|
|
44
|
+
exit_if(True,
|
|
45
|
+
f"Failed running Unittest, got exit code {ret}. try running manually using:\n\t{self._build_command('TARGET')}")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
'UnittestRunner',
|
|
50
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Literal
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class Bound:
|
|
7
|
+
operator: Literal["<", "<=", ">", ">="]
|
|
8
|
+
value: float
|
|
9
|
+
|
|
10
|
+
def compare_against(self, score: float) -> bool:
|
|
11
|
+
return {
|
|
12
|
+
">": score > self.value,
|
|
13
|
+
">=": score >= self.value,
|
|
14
|
+
"<": score < self.value,
|
|
15
|
+
"<=": score <= self.value,
|
|
16
|
+
}[self.operator]
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def from_string(s: str) -> 'Bound':
|
|
20
|
+
# the order of iteration matters, weak inequality operators should be first.
|
|
21
|
+
for op in [">=", "<=", ">", "<"]:
|
|
22
|
+
splits = s.split(op)
|
|
23
|
+
if len(splits) == 2:
|
|
24
|
+
return Bound(op, float(splits[-1])) # type:ignore
|
|
25
|
+
raise ValueError("Invalid 'Bound' format")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
'Bound'
|
|
30
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
@dataclass(order=True)
|
|
5
|
+
class Version:
|
|
6
|
+
@staticmethod
|
|
7
|
+
def from_str(version_str: str) -> "Version":
|
|
8
|
+
return Version(*list(map(int, version_str.split("."))))
|
|
9
|
+
|
|
10
|
+
major: int = 0
|
|
11
|
+
minor: int = 0
|
|
12
|
+
patch: int = 0
|
|
13
|
+
|
|
14
|
+
def __init__(self, major: int = 0, minor: int = 0, patch: int = 0):
|
|
15
|
+
if not all(map(lambda x: isinstance(x, int) and x >= 0, [major, minor, patch])):
|
|
16
|
+
raise ValueError("Version supports positive integers only")
|
|
17
|
+
self.major = major
|
|
18
|
+
self.minor = minor
|
|
19
|
+
self.patch = patch
|
|
20
|
+
|
|
21
|
+
def __str__(self) -> str:
|
|
22
|
+
return f"{self.major}.{self.minor}.{self.patch}"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
'Version'
|
|
27
|
+
]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import Optional, Union
|
|
2
|
+
|
|
3
|
+
from danielutils import get_python_version
|
|
4
|
+
|
|
5
|
+
from .custom_types import Path
|
|
6
|
+
from .structures import Version
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def validate_version(version: Optional[Union[str, Version]]) -> Version:
|
|
10
|
+
if version is None:
|
|
11
|
+
version = Version(0, 0, 1)
|
|
12
|
+
else:
|
|
13
|
+
version: Version = version if isinstance(version, Version) else Version.from_str(version) # type: ignore
|
|
14
|
+
return version
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def validate_python_version(min_python: Optional[Version]) -> Version:
|
|
18
|
+
if min_python is not None:
|
|
19
|
+
return min_python
|
|
20
|
+
return Version(*get_python_version())
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def validate_keywords(keywords: Optional[list[str]]) -> list[str]:
|
|
24
|
+
if keywords is None:
|
|
25
|
+
return []
|
|
26
|
+
return keywords
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def validate_dependencies(dependencies: Optional[list[str]]) -> list[str]:
|
|
30
|
+
if dependencies is None:
|
|
31
|
+
return []
|
|
32
|
+
return dependencies
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def validate_source(name: str, src: Optional[Path] = None) -> Path:
|
|
36
|
+
if src is not None:
|
|
37
|
+
return src
|
|
38
|
+
return f"./{name}"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
"validate_version",
|
|
43
|
+
"validate_python_version",
|
|
44
|
+
"validate_keywords",
|
|
45
|
+
"validate_dependencies"
|
|
46
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: quickpub
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: A python package to quickly configure and publish a new package
|
|
5
5
|
Author-email: danielnachumdev <danielnachumdev@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -30,7 +30,38 @@ Classifier: Development Status :: 3 - Alpha
|
|
|
30
30
|
Classifier: Intended Audience :: Developers
|
|
31
31
|
Classifier: Programming Language :: Python :: 3
|
|
32
32
|
Classifier: Operating System :: Microsoft :: Windows
|
|
33
|
-
Requires-Python: >=3.
|
|
33
|
+
Requires-Python: >=3.9.19
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
35
36
|
|
|
36
37
|
# quickpub
|
|
38
|
+
|
|
39
|
+
Example usage of how this package was published
|
|
40
|
+
```python
|
|
41
|
+
from quickpub import publish, AdditionalConfiguration, MypyRunner, PylintRunner, UnittestRunner
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def main() -> None:
|
|
45
|
+
publish(
|
|
46
|
+
name="quickpub",
|
|
47
|
+
version="0.8.0",
|
|
48
|
+
author="danielnachumdev",
|
|
49
|
+
author_email="danielnachumdev@gmail.com",
|
|
50
|
+
description="A python package to quickly configure and publish a new package",
|
|
51
|
+
homepage="https://github.com/danielnachumdev/quickpub",
|
|
52
|
+
dependencies=["twine", "danielutils"],
|
|
53
|
+
min_python="3.9.19",
|
|
54
|
+
config=AdditionalConfiguration(
|
|
55
|
+
runners=[
|
|
56
|
+
MypyRunner(),
|
|
57
|
+
PylintRunner(),
|
|
58
|
+
UnittestRunner(),
|
|
59
|
+
]
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == '__main__':
|
|
65
|
+
main()
|
|
66
|
+
|
|
67
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README.md
|
|
4
|
+
pyproject.toml
|
|
5
|
+
setup.py
|
|
6
|
+
quickpub/__init__.py
|
|
7
|
+
quickpub/__main__.py
|
|
8
|
+
quickpub/classifiers.py
|
|
9
|
+
quickpub/custom_types.py
|
|
10
|
+
quickpub/enforcers.py
|
|
11
|
+
quickpub/files.py
|
|
12
|
+
quickpub/functions.py
|
|
13
|
+
quickpub/proxy.py
|
|
14
|
+
quickpub/py.typed
|
|
15
|
+
quickpub/validators.py
|
|
16
|
+
quickpub.egg-info/PKG-INFO
|
|
17
|
+
quickpub.egg-info/SOURCES.txt
|
|
18
|
+
quickpub.egg-info/dependency_links.txt
|
|
19
|
+
quickpub.egg-info/requires.txt
|
|
20
|
+
quickpub.egg-info/top_level.txt
|
|
21
|
+
quickpub/runnables/__init__.py
|
|
22
|
+
quickpub/runnables/common_check.py
|
|
23
|
+
quickpub/runnables/configurable.py
|
|
24
|
+
quickpub/runnables/has_optional_executable.py
|
|
25
|
+
quickpub/runnables/runnable.py
|
|
26
|
+
quickpub/runnables/implementations/__init__.py
|
|
27
|
+
quickpub/runnables/implementations/mypy.py
|
|
28
|
+
quickpub/runnables/implementations/pylint.py
|
|
29
|
+
quickpub/runnables/implementations/pytest.py
|
|
30
|
+
quickpub/runnables/implementations/unittest.py
|
|
31
|
+
quickpub/structures/__init__.py
|
|
32
|
+
quickpub/structures/additional_configuration.py
|
|
33
|
+
quickpub/structures/bound.py
|
|
34
|
+
quickpub/structures/version.py
|
quickpub-0.5.0/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# quickpub
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
from typing import Optional, Union
|
|
2
|
-
from danielutils import get_python_version
|
|
3
|
-
from .publish import build, upload, commit, metrics
|
|
4
|
-
from .structures import Version, Config
|
|
5
|
-
from .files import create_toml, create_setup
|
|
6
|
-
from .classifiers import *
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def publish(
|
|
10
|
-
*,
|
|
11
|
-
name: str,
|
|
12
|
-
version: Optional[Union[Version, str]] = None,
|
|
13
|
-
author: str,
|
|
14
|
-
author_email: str,
|
|
15
|
-
description: str,
|
|
16
|
-
homepage: str,
|
|
17
|
-
|
|
18
|
-
min_python: Optional[Union[Version, str]] = None,
|
|
19
|
-
|
|
20
|
-
keywords: Optional[list[str]] = None,
|
|
21
|
-
dependencies: Optional[list[str]] = None,
|
|
22
|
-
config: Optional[Config] = None
|
|
23
|
-
) -> None:
|
|
24
|
-
if version is None:
|
|
25
|
-
version: Version = None # type: ignore
|
|
26
|
-
else:
|
|
27
|
-
version: Version = version if isinstance(version, Version) else Version.from_str(version) # type: ignore
|
|
28
|
-
|
|
29
|
-
if min_python is None:
|
|
30
|
-
min_python = Version(*get_python_version())
|
|
31
|
-
if keywords is None:
|
|
32
|
-
keywords = []
|
|
33
|
-
|
|
34
|
-
if dependencies is None:
|
|
35
|
-
dependencies = []
|
|
36
|
-
|
|
37
|
-
create_setup()
|
|
38
|
-
create_toml(
|
|
39
|
-
name=name,
|
|
40
|
-
version=version,
|
|
41
|
-
author=author,
|
|
42
|
-
author_email=author_email,
|
|
43
|
-
description=description,
|
|
44
|
-
homepage=homepage,
|
|
45
|
-
keywords=keywords,
|
|
46
|
-
dependencies=dependencies,
|
|
47
|
-
classifiers=[
|
|
48
|
-
DevelopmentStatusClassifier.Alpha,
|
|
49
|
-
IntendedAudienceClassifier.Developers,
|
|
50
|
-
ProgrammingLanguageClassifier.Python3,
|
|
51
|
-
OperatingSystemClassifier.MicrosoftWindows
|
|
52
|
-
],
|
|
53
|
-
min_python=min_python
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
build()
|
|
57
|
-
upload(
|
|
58
|
-
name=name,
|
|
59
|
-
version=version
|
|
60
|
-
)
|
|
61
|
-
commit(
|
|
62
|
-
version=version
|
|
63
|
-
)
|
|
64
|
-
metrics()
|
|
65
|
-
|
|
66
|
-
# if __name__ == '__main__':
|
|
67
|
-
# publish()
|
quickpub-0.5.0/quickpub/proxy.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
@dataclass
|
|
5
|
-
class Version:
|
|
6
|
-
@staticmethod
|
|
7
|
-
def from_str(version_str: str) -> "Version":
|
|
8
|
-
return Version(*list(map(int, version_str.split("."))))
|
|
9
|
-
|
|
10
|
-
major: int = 0
|
|
11
|
-
minor: int = 0
|
|
12
|
-
patch: int = 0
|
|
13
|
-
|
|
14
|
-
def __str__(self) -> str:
|
|
15
|
-
return f"{self.major}.{self.minor}.{self.patch}"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
@dataclass
|
|
19
|
-
class Config:
|
|
20
|
-
pylint: bool = False
|
|
21
|
-
mypy: bool = False
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
__all__ = [
|
|
26
|
-
"Version",
|
|
27
|
-
"Config",
|
|
28
|
-
]
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
README.md
|
|
2
|
-
pyproject.toml
|
|
3
|
-
setup.py
|
|
4
|
-
quickpub/__init__.py
|
|
5
|
-
quickpub/__main__.py
|
|
6
|
-
quickpub/classifiers.py
|
|
7
|
-
quickpub/files.py
|
|
8
|
-
quickpub/proxy.py
|
|
9
|
-
quickpub/publish.py
|
|
10
|
-
quickpub/structures.py
|
|
11
|
-
quickpub.egg-info/PKG-INFO
|
|
12
|
-
quickpub.egg-info/SOURCES.txt
|
|
13
|
-
quickpub.egg-info/dependency_links.txt
|
|
14
|
-
quickpub.egg-info/requires.txt
|
|
15
|
-
quickpub.egg-info/top_level.txt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|