quickpub 0.0.1__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.
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.1
2
+ Name: quickpub
3
+ Version: 0.0.1
4
+ Summary: A python package to quickly configure and publish a new package
5
+ Author-email: danielnachumdev <danielnachumdev@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2022 danielnachumdev
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://github.com/danielnachumdev/quickpub
28
+ Project-URL: Bug Tracker, https://github.com/danielnachumdev/quickpub/issues
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: Programming Language :: Python :: 3
32
+ Classifier: Operating System :: Microsoft :: Windows
33
+ Requires-Python: >=3.10.13
34
+ Description-Content-Type: text/markdown
35
+
36
+ # quickpub
@@ -0,0 +1 @@
1
+ # quickpub
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "quickpub"
7
+ version = "0.0.1"
8
+ authors = [
9
+ { name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
10
+ ]
11
+ dependencies = ['twine', 'danielutils']
12
+ keywords = []
13
+ license = { "file" = "LISENCE" }
14
+ description = "A python package to quickly configure and publish a new package"
15
+ readme = "README.md"
16
+ requires-python = ">=3.10.13"
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "Programming Language :: Python :: 3",
21
+ "Operating System :: Microsoft :: Windows"
22
+ ]
23
+
24
+ [tool.setuptools]
25
+ packages = ["quickpub"]
26
+
27
+ [project.urls]
28
+ "Homepage" = "https://github.com/danielnachumdev/quickpub"
29
+ "Bug Tracker" = "https://github.com/danielnachumdev/quickpub/issues"
@@ -0,0 +1,2 @@
1
+ from .__main__ import publish
2
+ from .structures import *
@@ -0,0 +1,67 @@
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()
@@ -0,0 +1,72 @@
1
+ from abc import ABC, abstractmethod
2
+ from enum import Enum
3
+
4
+
5
+ class Classifier(Enum):
6
+ def _str(self) -> str:
7
+ return str(self.value)
8
+
9
+ @staticmethod
10
+ def _split_name(name: str) -> str:
11
+ words = []
12
+ current_word = ''
13
+
14
+ for char in name:
15
+ # Check if the character is uppercase
16
+ if char.isupper():
17
+ # If current_word is not empty, add it to words list
18
+ if current_word:
19
+ words.append(current_word)
20
+ # Start a new word with the uppercase character
21
+ current_word = char
22
+ else:
23
+ # Add lowercase character to current_word
24
+ current_word += char
25
+
26
+ # Add the last word to the list
27
+ if current_word:
28
+ words.append(current_word)
29
+
30
+ return " ".join(words[:-1])
31
+
32
+ def __str__(self) -> str:
33
+ name = Classifier._split_name(self.__class__.__qualname__)
34
+ value = self._str()
35
+ return f"{name} :: {value}"
36
+
37
+
38
+ class DevelopmentStatusClassifier(Classifier):
39
+ # https://pypi.org/classifiers/
40
+ Planning = 1
41
+ PreAlpha = 2
42
+ Alpha = 3
43
+ Beta = 4
44
+ Production = 5
45
+ Stable = 5
46
+ Mature = 6
47
+ Inactive = 7
48
+
49
+ def _str(self) -> str:
50
+ return f"{self.value} - {self.name}"
51
+
52
+
53
+ class IntendedAudienceClassifier(Classifier):
54
+ CustomerService = "CustomerService"
55
+ Developers = "Developers"
56
+
57
+
58
+ class ProgrammingLanguageClassifier(Classifier):
59
+ Python3 = "Python :: 3"
60
+
61
+
62
+ class OperatingSystemClassifier(Classifier):
63
+ MicrosoftWindows = "Microsoft :: Windows"
64
+
65
+
66
+ __all__ = [
67
+ "Classifier",
68
+ "DevelopmentStatusClassifier",
69
+ "IntendedAudienceClassifier",
70
+ "ProgrammingLanguageClassifier",
71
+ "OperatingSystemClassifier"
72
+ ]
@@ -0,0 +1,60 @@
1
+ from typing import Optional
2
+
3
+ from .classifiers import Classifier
4
+ from .structures import Version
5
+
6
+
7
+ def create_toml(
8
+ *,
9
+ name: str,
10
+ version: Version,
11
+ author: str,
12
+ author_email: str,
13
+ description: str,
14
+ homepage: str,
15
+ keywords: list[str],
16
+ min_python: Version,
17
+ dependencies: list[str],
18
+ classifiers: list[Classifier]
19
+ ) -> None:
20
+ classifiers_string = ",\n\t".join([f"\"{str(c)}\"" for c in classifiers])
21
+ if len(classifiers_string) > 0:
22
+ classifiers_string = f"\n\t{classifiers_string}\n"
23
+ s = f"""[build-system]
24
+ requires = ["setuptools>=61.0"]
25
+ build-backend = "setuptools.build_meta"
26
+
27
+ [project]
28
+ name = "{name}"
29
+ version = "{version}"
30
+ authors = [
31
+ {{ name = "{author}", email = "{author_email}" }},
32
+ ]
33
+ dependencies = {dependencies}
34
+ keywords = {keywords}
35
+ license = {{ "file" = "LISENCE" }}
36
+ description = "{description}"
37
+ readme = "README.md"
38
+ requires-python = ">={min_python}"
39
+ classifiers = [{classifiers_string}]
40
+
41
+ [tool.setuptools]
42
+ packages = ["{name}"]
43
+
44
+ [project.urls]
45
+ "Homepage" = "{homepage}"
46
+ "Bug Tracker" = "{homepage}/issues"
47
+ """
48
+ with open("pyproject.toml", "w", encoding="utf8") as f:
49
+ f.write(s)
50
+
51
+
52
+ def create_setup() -> None:
53
+ with open("./setup.py", "w", encoding="utf8") as f:
54
+ f.write("from setuptools import setup\n\nsetup()\n")
55
+
56
+
57
+ __all__ = [
58
+ "create_setup",
59
+ "create_toml"
60
+ ]
@@ -0,0 +1,195 @@
1
+ from danielutils import cm, info, error
2
+
3
+ from .structures import Version
4
+
5
+
6
+ def prev_main():
7
+ import re
8
+ from danielutils import cmrt, cm, read_file, get_files, directory_exists, create_directory # type:ignore
9
+
10
+ NAME = "danielutils"
11
+
12
+ VERSION_PATTERN = r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
13
+ SETUP = "./setup.py"
14
+ TOML = "./pyproject.toml"
15
+ README = "./README.md"
16
+ DIST = "./dist"
17
+ REPORTS = "./reports"
18
+
19
+ def get_latest(ver: str = '0.0.0') -> str:
20
+ """returns the latest version currently in the DIST fuller
21
+
22
+ Args:
23
+ version (str, optional): the version to compare against. Defaults to '0.0.0'.
24
+
25
+ Returns:
26
+ str: the biggest version number
27
+ """
28
+ if not directory_exists(DIST):
29
+ return ver
30
+ DIST_PATTERN = NAME + r"-(\d+)\.(\d+)\.(\d+)\.tar\.gz"
31
+ best = ver
32
+ for filename in get_files(DIST):
33
+ a1, b1, c1 = best.split(".")
34
+ match = re.match(DIST_PATTERN, filename)
35
+ if match:
36
+ a2, b2, c2 = match.groups()
37
+ other_version = f"{a2}.{b2}.{c2}"
38
+ if int(a2) > int(a1):
39
+ best = other_version
40
+ elif int(a2) == int(a1):
41
+ if int(b2) > int(b1):
42
+ best = other_version
43
+ elif int(b2) == int(b1):
44
+ if int(c2) > int(c1):
45
+ best = other_version
46
+ return best
47
+
48
+ def main(ver: str):
49
+ """main function, create a new release and update the files and call terminal to upload the release
50
+
51
+ Args:
52
+ version (str): the new version
53
+ """
54
+
55
+ latest = get_latest(ver)
56
+ if latest != ver:
57
+ print(f"{ver} is not the latest version, found {latest}, cancelling...")
58
+ exit()
59
+ print("Creating new distribution...")
60
+ ret, stdout, stderr = cm("python", "setup.py", "sdist")
61
+ if ret != 0:
62
+ print(stderr)
63
+ exit()
64
+ print("Created dist successfully")
65
+ ret, stdout, stderr = cm("wt.exe",
66
+ "twine", "upload", "--config-file", ".pypirc", f"dist/{NAME}-{ver}.tar.gz")
67
+
68
+ def pytest() -> bool:
69
+ """run pytest
70
+
71
+ Returns:
72
+ bool: success status
73
+ """
74
+
75
+ def has_fails(pytest_out: str) -> bool:
76
+ RE = r'=+ (?:(?P<FAIL>\d+ failed), )?(?P<PASS>\d+ passed) in [\d\.]+s =+'
77
+ if not re.match(RE, pytest_out):
78
+ print("Failed to match pytest output")
79
+ return True
80
+
81
+ res = re.findall(RE, pytest_out)[0]
82
+ failed = int(res[0].split()[0]) if res[0] != "" else 0
83
+ return failed > 0
84
+
85
+ COMMAND = "pytest"
86
+ if input("Do you want to generate a report as well? <y|n>: ") == "y":
87
+ COMMAND += " --html=pytest_report.html"
88
+ COMMAND += f" > {REPORTS}/pytest.txt"
89
+ print("running pytest")
90
+ code, stdout, stderr = cm(COMMAND)
91
+ if code != 0:
92
+ err = stderr.decode()
93
+ if err != "":
94
+ print(err)
95
+ return False
96
+ with open(f"{REPORTS}/pytest.txt", "r", encoding="utf8") as f:
97
+ summary = f.readlines()[-1]
98
+ if has_fails(summary):
99
+ print(summary)
100
+ return False
101
+ return True
102
+
103
+ def pylint(config_file_path: str = "./.pylintrc") -> None:
104
+ """run pylint
105
+ """
106
+ print("running pylint...")
107
+ for i, line in cmrt("pylint", "--rcfile", config_file_path,
108
+ f"./{NAME}", ">", f"{REPORTS}/pylint.txt"):
109
+ print(line.decode(), end="")
110
+
111
+ def git(ver: str) -> None:
112
+ """will add recent changes and automatically commit to git after the publication
113
+ """
114
+
115
+ def mypy(config_file_path: str = "mypy.ini") -> None:
116
+ """run mypy
117
+ """
118
+ print("running mypy")
119
+ with open(f"{REPORTS}/mypy.txt", "w", encoding="utf8") as f:
120
+ for i, line in cmrt("mypy", "--config-file", config_file_path,
121
+ f"./{NAME}"):
122
+ f.write(line.decode())
123
+ print(line.decode(), end="")
124
+
125
+ if __name__ == "__main__":
126
+ if not directory_exists(REPORTS):
127
+ create_directory(REPORTS)
128
+ has_passed_tests = pytest()
129
+ if True:
130
+ print("Passed all tests!")
131
+ pylint()
132
+ mypy()
133
+ version = input(
134
+ f"Please supply a new version number (LATEST = {get_latest()}): ")
135
+ if re.match(VERSION_PATTERN, version):
136
+ main(version)
137
+ git(version)
138
+ print("DONE")
139
+ else:
140
+ print("invalid version. example 1.0.5.20")
141
+
142
+
143
+ def build(
144
+ *,
145
+ verbose: bool = True
146
+ ) -> None:
147
+ if verbose:
148
+ info("Creating new distribution...")
149
+ ret, stdout, stderr = cm("python", "setup.py", "sdist")
150
+ if ret != 0:
151
+ error(stderr.decode(encoding="utf8"))
152
+ exit(1)
153
+
154
+
155
+ def upload(
156
+ *,
157
+ name: str,
158
+ version: Version,
159
+ verbose: bool = True
160
+ ) -> None:
161
+ if verbose:
162
+ info("Uploading")
163
+ ret, stdout, stderr = cm("wt.exe", "twine", "upload", "--config-file", ".pypirc", f"dist/{name}-{version}.tar.gz")
164
+ if ret != 0:
165
+ error(stderr.decode(encoding="utf8"))
166
+ exit(1)
167
+
168
+
169
+ def commit(
170
+ *,
171
+ version: Version,
172
+ verbose: bool = True
173
+ ) -> None:
174
+ if verbose:
175
+ info("Git")
176
+ info("\tStaging")
177
+ cm("git add .")
178
+ if verbose:
179
+ info("\tCommitting")
180
+ cm(f"git commit -m \"updated to version {version}\"")
181
+ if verbose:
182
+ info("\tPushing")
183
+ cm("git push")
184
+
185
+
186
+ def metrics():
187
+ pass
188
+
189
+
190
+ __all__ = [
191
+ "build",
192
+ "upload",
193
+ "commit",
194
+ "metrics"
195
+ ]
@@ -0,0 +1,28 @@
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
+ ]
@@ -0,0 +1,36 @@
1
+ Metadata-Version: 2.1
2
+ Name: quickpub
3
+ Version: 0.0.1
4
+ Summary: A python package to quickly configure and publish a new package
5
+ Author-email: danielnachumdev <danielnachumdev@gmail.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2022 danielnachumdev
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+ Project-URL: Homepage, https://github.com/danielnachumdev/quickpub
28
+ Project-URL: Bug Tracker, https://github.com/danielnachumdev/quickpub/issues
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: Programming Language :: Python :: 3
32
+ Classifier: Operating System :: Microsoft :: Windows
33
+ Requires-Python: >=3.10.13
34
+ Description-Content-Type: text/markdown
35
+
36
+ # quickpub
@@ -0,0 +1,14 @@
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/publish.py
9
+ quickpub/structures.py
10
+ quickpub.egg-info/PKG-INFO
11
+ quickpub.egg-info/SOURCES.txt
12
+ quickpub.egg-info/dependency_links.txt
13
+ quickpub.egg-info/requires.txt
14
+ quickpub.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ twine
2
+ danielutils
@@ -0,0 +1 @@
1
+ quickpub
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from setuptools import setup
2
+
3
+ setup()