quickpub 1.0.2__tar.gz → 1.0.3__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 (47) hide show
  1. {quickpub-1.0.2 → quickpub-1.0.3}/LICENSE +20 -20
  2. {quickpub-1.0.2/quickpub.egg-info → quickpub-1.0.3}/PKG-INFO +16 -13
  3. quickpub-1.0.3/README.md +35 -0
  4. {quickpub-1.0.2 → quickpub-1.0.3}/pyproject.toml +1 -1
  5. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/__main__.py +19 -22
  6. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/qa.py +10 -12
  7. quickpub-1.0.3/quickpub/strategies/__init__.py +6 -0
  8. quickpub-1.0.2/quickpub/strategies/build_strategy.py → quickpub-1.0.3/quickpub/strategies/build_schema.py +2 -2
  9. quickpub-1.0.3/quickpub/strategies/implementations/__init__.py +9 -0
  10. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/strategies/implementations/conda_python_version_manager_strategy.py +4 -4
  11. quickpub-1.0.2/quickpub/strategies/implementations/git_upload_strategy.py → quickpub-1.0.3/quickpub/strategies/implementations/github_upload_target.py +3 -3
  12. quickpub-1.0.2/quickpub/strategies/implementations/mypy_qa_strategy.py → quickpub-1.0.3/quickpub/strategies/implementations/mypy_qa_runner.py +4 -4
  13. quickpub-1.0.2/quickpub/strategies/implementations/pylint_qa_strategy.py → quickpub-1.0.3/quickpub/strategies/implementations/pylint_qa_runner.py +4 -4
  14. quickpub-1.0.2/quickpub/strategies/implementations/pypirc_upload_strategy.py → quickpub-1.0.3/quickpub/strategies/implementations/pypirc_upload_target.py +5 -5
  15. quickpub-1.0.3/quickpub/strategies/implementations/pytest_qa_runner.py +95 -0
  16. quickpub-1.0.2/quickpub/strategies/implementations/setuptools_build_strategy.py → quickpub-1.0.3/quickpub/strategies/implementations/setuptools_build_schema.py +3 -3
  17. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/strategies/implementations/system_interpreter.py +4 -4
  18. quickpub-1.0.2/quickpub/strategies/implementations/unittest_qa_strategy.py → quickpub-1.0.3/quickpub/strategies/implementations/unittest_qa_runner.py +5 -6
  19. quickpub-1.0.2/quickpub/strategies/python_version_manager_strategy.py → quickpub-1.0.3/quickpub/strategies/python_provider.py +2 -2
  20. quickpub-1.0.3/quickpub/strategies/quality_assurance_runner.py +167 -0
  21. quickpub-1.0.2/quickpub/strategies/upload_strategy.py → quickpub-1.0.3/quickpub/strategies/upload_target.py +2 -2
  22. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/structures/dependency.py +1 -1
  23. {quickpub-1.0.2 → quickpub-1.0.3/quickpub.egg-info}/PKG-INFO +16 -13
  24. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub.egg-info/SOURCES.txt +11 -11
  25. quickpub-1.0.2/README.md +0 -32
  26. quickpub-1.0.2/quickpub/strategies/__init__.py +0 -6
  27. quickpub-1.0.2/quickpub/strategies/implementations/__init__.py +0 -9
  28. quickpub-1.0.2/quickpub/strategies/implementations/pytest_qa_strategy.py +0 -1
  29. quickpub-1.0.2/quickpub/strategies/quality_assurance_strategy.py +0 -98
  30. {quickpub-1.0.2 → quickpub-1.0.3}/MANIFEST.in +0 -0
  31. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/__init__.py +0 -0
  32. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/classifiers.py +0 -0
  33. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/enforcers.py +0 -0
  34. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/files.py +0 -0
  35. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/functions.py +0 -0
  36. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/proxy.py +0 -0
  37. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/py.typed +0 -0
  38. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/strategies/quickpub_strategy.py +0 -0
  39. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/structures/__init__.py +0 -0
  40. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/structures/bound.py +0 -0
  41. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/structures/version.py +0 -0
  42. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub/validators.py +0 -0
  43. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub.egg-info/dependency_links.txt +0 -0
  44. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub.egg-info/requires.txt +0 -0
  45. {quickpub-1.0.2 → quickpub-1.0.3}/quickpub.egg-info/top_level.txt +0 -0
  46. {quickpub-1.0.2 → quickpub-1.0.3}/setup.cfg +0 -0
  47. {quickpub-1.0.2 → quickpub-1.0.3}/setup.py +0 -0
@@ -1,21 +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
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
21
  SOFTWARE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quickpub
3
- Version: 1.0.2
3
+ Version: 1.0.3
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
@@ -34,35 +34,38 @@ Requires-Python: >=3.8.0
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
36
 
37
- # quickpub V0.8.3
37
+ # quickpub V1.0.3
38
38
  **Tested python versions**: `3.8.0`, `3.9.0`, `3.10.13`,
39
39
 
40
40
  Example usage of how this package was published
41
41
  ```python
42
- from quickpub import publish, AdditionalConfiguration, MypyRunner, PylintRunner, UnittestRunner
42
+ from quickpub import publish, MypyRunner, PylintRunner, UnittestRunner, CondaPythonProvider, \
43
+ PypircUploadTarget, SetuptoolsBuildSchema, GithubUploadTarget
43
44
 
44
45
 
45
46
  def main() -> None:
46
47
  publish(
47
48
  name="quickpub",
48
- version="0.8.0",
49
+ version="1.0.3",
49
50
  author="danielnachumdev",
50
51
  author_email="danielnachumdev@gmail.com",
51
52
  description="A python package to quickly configure and publish a new package",
52
53
  homepage="https://github.com/danielnachumdev/quickpub",
53
- dependencies=["twine", "danielutils"],
54
- min_python="3.9.19",
55
- config=AdditionalConfiguration(
56
- runners=[
57
- MypyRunner(bound="<15"),
58
- PylintRunner(bound=">=0.8"),
59
- UnittestRunner(bound=">=0.8"),
60
- ]
61
- )
54
+ build_schemas=[SetuptoolsBuildSchema()],
55
+ upload_targets=[PypircUploadTarget(), GithubUploadTarget()],
56
+ python_interpreter_provider=CondaPythonProvider(["base", "390", "380"]),
57
+ quality_assurance_runners=[
58
+ MypyRunner(bound="<=15", configuration_path="./mypy.ini"),
59
+ PylintRunner(bound=">=0.8", configuration_path="./.pylintrc"),
60
+ UnittestRunner(bound=">=0.8"),
61
+ ],
62
+ dependencies=["danielutils>=0.9.90"],
63
+ min_python="3.8.0",
62
64
  )
63
65
 
64
66
 
65
67
  if __name__ == '__main__':
66
68
  main()
67
69
 
70
+
68
71
  ```
@@ -0,0 +1,35 @@
1
+ # quickpub V1.0.3
2
+ **Tested python versions**: `3.8.0`, `3.9.0`, `3.10.13`,
3
+
4
+ Example usage of how this package was published
5
+ ```python
6
+ from quickpub import publish, MypyRunner, PylintRunner, UnittestRunner, CondaPythonProvider, \
7
+ PypircUploadTarget, SetuptoolsBuildSchema, GithubUploadTarget
8
+
9
+
10
+ def main() -> None:
11
+ publish(
12
+ name="quickpub",
13
+ version="1.0.3",
14
+ author="danielnachumdev",
15
+ author_email="danielnachumdev@gmail.com",
16
+ description="A python package to quickly configure and publish a new package",
17
+ homepage="https://github.com/danielnachumdev/quickpub",
18
+ build_schemas=[SetuptoolsBuildSchema()],
19
+ upload_targets=[PypircUploadTarget(), GithubUploadTarget()],
20
+ python_interpreter_provider=CondaPythonProvider(["base", "390", "380"]),
21
+ quality_assurance_runners=[
22
+ MypyRunner(bound="<=15", configuration_path="./mypy.ini"),
23
+ PylintRunner(bound=">=0.8", configuration_path="./.pylintrc"),
24
+ UnittestRunner(bound=">=0.8"),
25
+ ],
26
+ dependencies=["danielutils>=0.9.90"],
27
+ min_python="3.8.0",
28
+ )
29
+
30
+
31
+ if __name__ == '__main__':
32
+ main()
33
+
34
+
35
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quickpub"
7
- version = "1.0.2"
7
+ version = "1.0.3"
8
8
  authors = [
9
9
  { name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
10
10
  ]
@@ -2,8 +2,7 @@ import argparse
2
2
  from typing import Optional, Union, List, Any
3
3
  from danielutils import warning, file_exists, error
4
4
 
5
- from quickpub import SystemInterpreter
6
- from strategies import BuildStrategy, UploadStrategy, QualityAssuranceStrategy, PythonVersionManagerStrategy
5
+ from .strategies import BuildSchema, UploadTarget, QualityAssuranceRunner, PythonProvider, DefaultInterpreterProvider
7
6
  from .validators import validate_version, validate_python_version, validate_keywords, validate_dependencies, \
8
7
  validate_source
9
8
  from .structures import Version, Dependency
@@ -21,22 +20,20 @@ def publish(
21
20
  description: str,
22
21
  homepage: str,
23
22
 
24
- build_strategies: List[BuildStrategy],
25
- upload_strategies: List[UploadStrategy],
26
- quality_assurance_strategies: Optional[List[QualityAssuranceStrategy]] = None,
27
- python_version_manager_strategy: PythonVersionManagerStrategy = SystemInterpreter(),
23
+ build_schemas: List[BuildSchema],
24
+ upload_targets: List[UploadTarget],
25
+ quality_assurance_runners: Optional[List[QualityAssuranceRunner]] = None,
26
+ python_interpreter_provider: PythonProvider = DefaultInterpreterProvider(),
28
27
 
29
- explicit_src_folder_path: Optional[str] = None,
30
- version: Optional[Union[Version, str]] = None,
31
28
  readme_file_path: str = "./README.md",
32
29
  license_file_path: str = "./LICENSE",
33
-
30
+ version: Optional[Union[Version, str]] = None,
34
31
  min_python: Optional[Union[Version, str]] = None,
35
-
36
- keywords: Optional[List[str]] = None,
37
32
  dependencies: Optional[List[Union[str, Dependency]]] = None,
38
- demo: bool = False,
33
+ keywords: Optional[List[str]] = None,
34
+ explicit_src_folder_path: Optional[str] = None,
39
35
 
36
+ demo: bool = False,
40
37
  config: Optional[Any] = None,
41
38
  ) -> None:
42
39
  """The main function for publishing a package. It performs all necessary steps to prepare and publish the package.
@@ -46,10 +43,10 @@ def publish(
46
43
  :param author_email: The email of the author.
47
44
  :param description: A short description of the package.
48
45
  :param homepage: The homepage URL for the package (e.g., GitHub repository).
49
- :param quality_assurance_strategies: Strategies for quality assurance.
50
- :param build_strategies: Strategies for building the package.
51
- :param upload_strategies: Strategies for uploading the package.
52
- :param python_version_manager_strategy: Strategy for managing Python versions. Defaults to SystemInterpreter().
46
+ :param quality_assurance_runners: Strategies for quality assurance.
47
+ :param build_schemas: Strategies for building the package.
48
+ :param upload_targets: Strategies for uploading the package.
49
+ :param python_interpreter_provider: Strategy for managing Python versions. Defaults to SystemInterpreter().
53
50
  :param explicit_src_folder_path: The path to the source code of the package. Defaults to the current working directory/<name>.
54
51
  :param version: The version for the new distribution. Defaults to "0.0.1".
55
52
  :param readme_file_path: The path to the README file. Defaults to "./README.md".
@@ -79,12 +76,12 @@ def publish(
79
76
  validated_dependencies: List[Dependency] = validate_dependencies(dependencies)
80
77
  enforce_remote_correct_version(name, version)
81
78
 
82
- if quality_assurance_strategies is None:
83
- quality_assurance_strategies = []
79
+ if quality_assurance_runners is None:
80
+ quality_assurance_runners = []
84
81
  try:
85
82
  res = qa(
86
- python_version_manager_strategy,
87
- quality_assurance_strategies,
83
+ python_interpreter_provider,
84
+ quality_assurance_runners,
88
85
  name,
89
86
  explicit_src_folder_path,
90
87
  validated_dependencies
@@ -122,9 +119,9 @@ def publish(
122
119
  )
123
120
  create_manifest(name=name)
124
121
  if not demo:
125
- for build_strategy in build_strategies:
122
+ for build_strategy in build_schemas:
126
123
  build_strategy.execute_strategy()
127
- for upload_strategy in upload_strategies:
124
+ for upload_strategy in upload_targets:
128
125
  upload_strategy.execute_strategy(name=name, version=version)
129
126
 
130
127
 
@@ -4,8 +4,7 @@ from functools import wraps
4
4
  from typing import Optional, ContextManager, List, Callable, Tuple, Dict, Union
5
5
  from danielutils import AttrContext, LayeredCommand, AsciiProgressBar, ColoredText, ProgressBarPool, TemporaryFile
6
6
 
7
- from quickpub import QualityAssuranceStrategy
8
- from .strategies import PythonVersionManagerStrategy # pylint: disable=relative-beyond-top-level
7
+ from .strategies import PythonProvider, QualityAssuranceRunner # pylint: disable=relative-beyond-top-level
9
8
  from .structures import Dependency, Version, Bound # pylint: disable=relative-beyond-top-level
10
9
  from .enforcers import exit_if # pylint: disable=relative-beyond-top-level
11
10
 
@@ -54,7 +53,7 @@ def global_import_sanity_check(package_name: str, executor: LayeredCommand, is_s
54
53
  VERSION_REGEX: re.Pattern = re.compile(r"^\d+\.\d+\.\d+$")
55
54
 
56
55
 
57
- def validate_dependencies(python_manager: PythonVersionManagerStrategy, required_dependencies: List[Dependency],
56
+ def validate_dependencies(python_manager: PythonProvider, required_dependencies: List[Dependency],
58
57
  executor: LayeredCommand,
59
58
  env_name: str, err_print_func: Callable) -> None:
60
59
  """
@@ -86,15 +85,15 @@ def validate_dependencies(python_manager: PythonVersionManagerStrategy, required
86
85
  (req, "Verion format of dependecy is not currently supported by quickpub"))
87
86
  elif isinstance(v, Dependency):
88
87
  if not req.is_satisfied_by(v.ver):
89
- not_installed_properly.append((req, "rInvalid version installed"))
88
+ not_installed_properly.append((req, "Invalid version installed"))
90
89
 
91
90
  exit_if(bool(not_installed_properly),
92
91
  f"On env '{env_name}' the following dependencies have problems: {(not_installed_properly)}",
93
92
  err_func=err_print_func)
94
93
 
95
94
 
96
- def create_progress_bar_pool(python_version_manager: PythonVersionManagerStrategy,
97
- quality_assurance_strategies: List[QualityAssuranceStrategy]) -> ProgressBarPool:
95
+ def create_progress_bar_pool(python_version_manager: PythonProvider,
96
+ quality_assurance_strategies: List[QualityAssuranceRunner]) -> ProgressBarPool:
98
97
  return ProgressBarPool(
99
98
  AsciiProgressBar,
100
99
  2,
@@ -123,17 +122,17 @@ def create_pool_print_error(pool: ProgressBarPool):
123
122
 
124
123
 
125
124
  def qa(
126
- python_version_manager: PythonVersionManagerStrategy,
127
- quality_assurance_strategies: List[QualityAssuranceStrategy],
125
+ python_version_manager: PythonProvider,
126
+ quality_assurance_strategies: List[QualityAssuranceRunner],
128
127
  package_name: str,
129
128
  src_folder_path: Optional[str],
130
129
  dependencies: list
131
130
  ) -> bool:
132
- from .strategies import SystemInterpreter
131
+ from .strategies import DefaultInterpreterProvider
133
132
  result = True
134
133
  if python_version_manager is None:
135
- python_version_manager = SystemInterpreter()
136
- is_system_interpreter = isinstance(python_version_manager, SystemInterpreter)
134
+ python_version_manager = DefaultInterpreterProvider()
135
+ is_system_interpreter = isinstance(python_version_manager, DefaultInterpreterProvider)
137
136
  pool = create_progress_bar_pool(python_version_manager, quality_assurance_strategies)
138
137
  pool_err = create_pool_print_error(pool)
139
138
  with MultiContext(
@@ -165,7 +164,6 @@ def qa(
165
164
  src_folder_path,
166
165
  executor,
167
166
  use_system_interpreter=is_system_interpreter,
168
- raise_on_fail=python_version_manager.exit_on_fail,
169
167
  print_func=pool_err,
170
168
  env_name=env_name
171
169
  )
@@ -0,0 +1,6 @@
1
+ from .implementations import *
2
+ from .upload_target import *
3
+ from .quality_assurance_runner import *
4
+ from .quickpub_strategy import *
5
+ from .build_schema import *
6
+ from .python_provider import *
@@ -3,7 +3,7 @@ from abc import abstractmethod
3
3
  from .quickpub_strategy import QuickpubStrategy
4
4
 
5
5
 
6
- class BuildStrategy(QuickpubStrategy):
6
+ class BuildSchema(QuickpubStrategy):
7
7
  def __init__(self, verbose: bool = True) -> None:
8
8
  self.verbose = verbose
9
9
 
@@ -12,5 +12,5 @@ class BuildStrategy(QuickpubStrategy):
12
12
 
13
13
 
14
14
  __all__ = [
15
- "BuildStrategy"
15
+ "BuildSchema"
16
16
  ]
@@ -0,0 +1,9 @@
1
+ from .pypirc_upload_target import *
2
+ from .github_upload_target import *
3
+ from .setuptools_build_schema import *
4
+ from .mypy_qa_runner import *
5
+ from .pylint_qa_runner import *
6
+ from .pytest_qa_runner import *
7
+ from .unittest_qa_runner import *
8
+ from .conda_python_version_manager_strategy import *
9
+ from .system_interpreter import *
@@ -1,15 +1,15 @@
1
1
  from typing import Tuple, Optional, Set, Iterator, List
2
2
  from danielutils import LayeredCommand, warning
3
3
 
4
- from ..python_version_manager_strategy import PythonVersionManagerStrategy
4
+ from ..python_provider import PythonProvider
5
5
 
6
6
 
7
- class CondaPythonVersionManagerStrategy(PythonVersionManagerStrategy):
7
+ class CondaPythonProvider(PythonProvider):
8
8
  def get_python_executable_name(self) -> str:
9
9
  return "python"
10
10
 
11
11
  def __init__(self, env_names: List[str]) -> None:
12
- PythonVersionManagerStrategy.__init__(self, requested_envs=env_names, explicit_versions=[], exit_on_fail=True)
12
+ PythonProvider.__init__(self, requested_envs=env_names, explicit_versions=[], exit_on_fail=True)
13
13
  self._cached_available_envs: Optional[Set[str]] = None
14
14
 
15
15
  def get_available_envs(self) -> Set[str]:
@@ -33,5 +33,5 @@ class CondaPythonVersionManagerStrategy(PythonVersionManagerStrategy):
33
33
 
34
34
 
35
35
  __all__ = [
36
- 'CondaPythonVersionManagerStrategy',
36
+ 'CondaPythonProvider',
37
37
  ]
@@ -1,8 +1,8 @@
1
1
  from danielutils import info
2
2
 
3
- from ..upload_strategy import UploadStrategy
3
+ from ..upload_target import UploadTarget
4
4
 
5
- class GitUploadStrategy(UploadStrategy):
5
+ class GithubUploadTarget(UploadTarget):
6
6
  def execute_strategy(self, version: str, **kwargs) -> None:
7
7
  from quickpub.proxy import cm
8
8
  from quickpub.enforcers import exit_if
@@ -22,5 +22,5 @@ class GitUploadStrategy(UploadStrategy):
22
22
 
23
23
 
24
24
  __all__ = [
25
- "GitUploadStrategy",
25
+ "GithubUploadTarget",
26
26
  ]
@@ -3,10 +3,10 @@ from typing import Optional, List
3
3
 
4
4
  from danielutils import LayeredCommand
5
5
 
6
- from ..quality_assurance_strategy import QualityAssuranceStrategy
6
+ from ..quality_assurance_runner import QualityAssuranceRunner
7
7
 
8
8
 
9
- class MypyRunner(QualityAssuranceStrategy):
9
+ class MypyRunner(QualityAssuranceRunner):
10
10
  def _install_dependencies(self, base: LayeredCommand) -> None:
11
11
  with base:
12
12
  base("pip install pylint")
@@ -23,8 +23,8 @@ class MypyRunner(QualityAssuranceStrategy):
23
23
 
24
24
  def __init__(self, bound: str = "<15", configuration_path: Optional[str] = None,
25
25
  executable_path: Optional[str] = None) -> None:
26
- QualityAssuranceStrategy.__init__(self, name="mypy", bound=bound, configuration_path=configuration_path,
27
- executable_path=executable_path)
26
+ QualityAssuranceRunner.__init__(self, name="mypy", bound=bound, configuration_path=configuration_path,
27
+ executable_path=executable_path)
28
28
 
29
29
  def _calculate_score(self, ret, lines: List[str], verbose: bool = False) -> float:
30
30
  from ...enforcers import exit_if
@@ -3,10 +3,10 @@ from typing import Optional, List
3
3
 
4
4
  from danielutils import LayeredCommand
5
5
 
6
- from strategies.quality_assurance_strategy import QualityAssuranceStrategy
6
+ from ..quality_assurance_runner import QualityAssuranceRunner
7
7
 
8
8
 
9
- class PylintRunner(QualityAssuranceStrategy):
9
+ class PylintRunner(QualityAssuranceRunner):
10
10
  def _install_dependencies(self, base: LayeredCommand) -> None:
11
11
  with base:
12
12
  base("pip install pylint")
@@ -15,8 +15,8 @@ class PylintRunner(QualityAssuranceStrategy):
15
15
 
16
16
  def __init__(self, bound: str = ">=0.8", configuration_path: Optional[str] = None,
17
17
  executable_path: Optional[str] = None) -> None:
18
- QualityAssuranceStrategy.__init__(self, name="pylint", bound=bound, configuration_path=configuration_path,
19
- executable_path=executable_path)
18
+ QualityAssuranceRunner.__init__(self, name="pylint", bound=bound, configuration_path=configuration_path,
19
+ executable_path=executable_path)
20
20
 
21
21
  def _build_command(self, target: str, use_system_interpreter: bool = False) -> str:
22
22
  command: str = self.get_executable()
@@ -2,12 +2,12 @@ import re
2
2
 
3
3
  from danielutils import file_exists, info
4
4
 
5
- from ..upload_strategy import UploadStrategy
5
+ from ..upload_target import UploadTarget
6
6
 
7
7
 
8
- class PypircUploadStrategy(UploadStrategy):
8
+ class PypircUploadTarget(UploadTarget):
9
9
  REGEX_PATTERN: re.Pattern = re.compile(
10
- r"\[distutils\]\nindex-servers =\n pypi\n testpypi\n\n\[pypi\]\nusername = __token__\npassword = .+\n\n\[testpypi\]\nusername = __token__\npassword = .+\n")
10
+ r"\[distutils\]\nindex-servers =\n pypi\n testpypi\n\n\[pypi\]\n username = __token__\n password = .+\n\n\[testpypi\]\n username = __token__\n password = .+\n?")
11
11
 
12
12
  def execute_strategy(self, *, name: str, version: str, **kwargs) -> None:
13
13
  from quickpub.proxy import cm
@@ -32,7 +32,7 @@ class PypircUploadStrategy(UploadStrategy):
32
32
  text = f.read()
33
33
  if not self.REGEX_PATTERN.match(text):
34
34
  raise RuntimeError(
35
- f"{self.__class__.__name__} checked the contents of '{self.pypirc_file_path}' and it failed to match the following regex: {self.REGEX_PATTERN.pattern}")
35
+ f"{self.__class__.__name__} checked the contents of '{self.pypirc_file_path}' and it failed to match the following regex: r\"{self.REGEX_PATTERN.pattern}\"")
36
36
 
37
37
  def __init__(self, pypirc_file_path: str = "./.pypirc", verbose: bool = False) -> None:
38
38
  super().__init__(verbose)
@@ -40,5 +40,5 @@ class PypircUploadStrategy(UploadStrategy):
40
40
 
41
41
 
42
42
  __all__ = [
43
- "PypircUploadStrategy"
43
+ "PypircUploadTarget"
44
44
  ]
@@ -0,0 +1,95 @@
1
+ import re
2
+ from typing import List, Union, Optional
3
+
4
+ from danielutils import LayeredCommand
5
+
6
+ from quickpub import Bound
7
+ from ..quality_assurance_runner import QualityAssuranceRunner
8
+
9
+
10
+ class PytestRunner(QualityAssuranceRunner):
11
+ """
12
+ PytestRunner is a concrete implementation of QualityAssuranceRunner specifically for running
13
+ pytest-based tests. It includes methods to build the pytest command, install pytest dependencies,
14
+ and calculate the test score based on pytest results.
15
+
16
+ Attributes:
17
+ PYTEST_REGEX (re.Pattern): A regex pattern to parse pytest results for passed and failed tests.
18
+ """
19
+
20
+ PYTEST_REGEX: re.Pattern = re.compile(
21
+ r"=+ (?:(?P<failed>\d+) failed,? )?(?:(?P<passed>\d+) passed )?in [\d\.]+s =+")
22
+
23
+ def __init__(
24
+ self, *,
25
+ bound: Union[str, Bound] = ">=0.8",
26
+ target: str = "./tests",
27
+ no_output_score: float = 0.0,
28
+ no_tests_score: float = 1.0
29
+ ):
30
+ """
31
+ Initializes the PytestRunner with a bound and target directory for tests.
32
+
33
+ :param bound: The bound representing acceptable limits, either as a string or a Bound object.
34
+ Default is ">=0.8".
35
+ :param target: The target directory containing the tests. Default is "./tests".
36
+ """
37
+ super().__init__(
38
+ name="pytest",
39
+ bound=bound,
40
+ target=target
41
+ )
42
+ if not (0.0 <= no_tests_score <= 1.0):
43
+ raise RuntimeError("no_tests_score should be between 0.0 and 1.0 (including both).")
44
+ self.no_tests_score = no_tests_score
45
+
46
+ if not (0.0 <= no_output_score <= 1.0):
47
+ raise RuntimeError("no_output_score should be between 0.0 and 1.0 (including both).")
48
+ self.no_output_score = no_output_score
49
+
50
+ def _build_command(self, target: str, use_system_interpreter: bool = False) -> str:
51
+ """
52
+ Builds the command to run pytest on the specified target.
53
+
54
+ :param target: The target directory containing the tests.
55
+ :param use_system_interpreter: Whether to use the system interpreter. Default is False.
56
+ :return: The command to run pytest as a string.
57
+ """
58
+ if self.has_config:
59
+ return "pytest"
60
+ return f"pytest {self.target}"
61
+
62
+ def _install_dependencies(self, base: LayeredCommand) -> None:
63
+ """
64
+ Installs pytest and its dependencies.
65
+
66
+ :param base: The base LayeredCommand object for executing commands.
67
+ """
68
+ with base:
69
+ base("pip install pytest")
70
+
71
+ def _calculate_score(self, ret: int, command_output: List[str], *, verbose: bool = False) -> float:
72
+ """
73
+ Calculates the test score based on the pytest command output.
74
+
75
+ :param ret: The return code of the pytest command.
76
+ :param command_output: The output of the pytest command as a list of strings.
77
+ :param verbose: Whether to output verbose logs. Default is False.
78
+ :return: The calculated test score as a float.
79
+ """
80
+ if len(command_output) == 0:
81
+ return self.no_output_score
82
+ rating_line = command_output[-1]
83
+ if "no tests ran" in rating_line:
84
+ return self.no_tests_score
85
+ if not (m := self.PYTEST_REGEX.match(rating_line)):
86
+ raise SystemExit(1)
87
+
88
+ dct = m.groupdict()
89
+ failed = int(dct["failed"] or "0")
90
+ passed = int(dct["passed"] or "0")
91
+ assert failed >= 0
92
+ assert passed >= 0
93
+ if failed + passed == 0:
94
+ return self.no_tests_score
95
+ return passed / (passed + failed)
@@ -1,9 +1,9 @@
1
1
  from danielutils import info
2
2
 
3
- from ..build_strategy import BuildStrategy
3
+ from ..build_schema import BuildSchema
4
4
 
5
5
 
6
- class SetuptoolsBuildStrategy(BuildStrategy):
6
+ class SetuptoolsBuildSchema(BuildSchema):
7
7
  def execute_strategy(self, *args, **kwargs) -> None:
8
8
  from quickpub.proxy import cm
9
9
  from quickpub.enforcers import exit_if
@@ -17,5 +17,5 @@ class SetuptoolsBuildStrategy(BuildStrategy):
17
17
 
18
18
 
19
19
  __all__ = [
20
- "SetuptoolsBuildStrategy",
20
+ "SetuptoolsBuildSchema",
21
21
  ]
@@ -3,15 +3,15 @@ from typing import Set, Tuple, Iterator
3
3
 
4
4
  from danielutils import LayeredCommand
5
5
 
6
- from ..python_version_manager_strategy import PythonVersionManagerStrategy
6
+ from ..python_provider import PythonProvider
7
7
 
8
8
 
9
- class SystemInterpreter(PythonVersionManagerStrategy):
9
+ class DefaultInterpreterProvider(PythonProvider):
10
10
  def get_python_executable_name(self) -> str:
11
11
  return sys.executable
12
12
 
13
13
  def __init__(self) -> None:
14
- PythonVersionManagerStrategy.__init__(self, requested_envs=["system"], explicit_versions=[], exit_on_fail=True)
14
+ PythonProvider.__init__(self, requested_envs=["system"], explicit_versions=[], exit_on_fail=True)
15
15
 
16
16
  def __iter__(self) -> Iterator[Tuple[str, LayeredCommand]]:
17
17
  return iter([("system", LayeredCommand(""))])
@@ -21,5 +21,5 @@ class SystemInterpreter(PythonVersionManagerStrategy):
21
21
 
22
22
 
23
23
  __all__ = [
24
- "SystemInterpreter",
24
+ "DefaultInterpreterProvider",
25
25
  ]
@@ -3,10 +3,10 @@ import os
3
3
  from typing import Optional, List
4
4
  from danielutils import get_current_working_directory, set_current_working_directory, LayeredCommand, warning
5
5
 
6
- from strategies.quality_assurance_strategy import QualityAssuranceStrategy
6
+ from ..quality_assurance_runner import QualityAssuranceRunner
7
7
 
8
8
 
9
- class UnittestRunner(QualityAssuranceStrategy):
9
+ class UnittestRunner(QualityAssuranceRunner):
10
10
  def _install_dependencies(self, base: LayeredCommand) -> None:
11
11
  return None
12
12
 
@@ -23,7 +23,7 @@ class UnittestRunner(QualityAssuranceStrategy):
23
23
  RATING_PATTERN: re.Pattern = re.compile(r".*?([\d\.\/]+)")
24
24
 
25
25
  def __init__(self, target: Optional[str] = "./tests", bound: str = ">=0.8") -> None:
26
- QualityAssuranceStrategy.__init__(self, name="unittest", bound=bound, target=target)
26
+ QualityAssuranceRunner.__init__(self, name="unittest", bound=bound, target=target)
27
27
  self._cwd = ""
28
28
 
29
29
  def _build_command(self, src: str, *args, use_system_interpreter: bool = False) -> str:
@@ -33,7 +33,6 @@ class UnittestRunner(QualityAssuranceStrategy):
33
33
  return command # f"cd {self.target}; {command}" # f"; cd {self.target}"
34
34
 
35
35
  def _calculate_score(self, ret: int, lines: List[str], *, verbose: bool = False) -> float:
36
- from ...enforcers import exit_if
37
36
  num_tests_line = lines[-3]
38
37
  num_failed_line = lines[-1] if lines[-1] != "OK" else "0"
39
38
  try:
@@ -48,8 +47,8 @@ class UnittestRunner(QualityAssuranceStrategy):
48
47
 
49
48
  return 1.0 - (float(num_failed) / float(num_tests))
50
49
  except:
51
- exit_if(True,
52
- f"Failed running Unittest, got exit code {ret}. try running manually using: {self._build_command('TARGET')}")
50
+ raise SystemExit(f"Failed running Unittest, got exit code {ret}. "
51
+ f"try running manually using: {self._build_command('TARGET')}")
53
52
 
54
53
 
55
54
  __all__ = [
@@ -4,7 +4,7 @@ from typing import Tuple, Set, Iterator, List
4
4
  from danielutils import LayeredCommand
5
5
 
6
6
 
7
- class PythonVersionManagerStrategy(QuickpubStrategy):
7
+ class PythonProvider(QuickpubStrategy):
8
8
  def __init__(self, auto_install_dependencies: bool = True, *, requested_envs: List[str],
9
9
  explicit_versions: List[str],
10
10
  exit_on_fail: bool = False) -> None:
@@ -27,5 +27,5 @@ class PythonVersionManagerStrategy(QuickpubStrategy):
27
27
 
28
28
 
29
29
  __all__ = [
30
- 'PythonVersionManagerStrategy'
30
+ 'PythonProvider'
31
31
  ]
@@ -0,0 +1,167 @@
1
+ import sys
2
+ from abc import abstractmethod
3
+ from typing import Union, List, Optional, cast
4
+ from danielutils import LayeredCommand, get_os, OSType, file_exists
5
+
6
+ from quickpub import Bound
7
+
8
+
9
+ class Configurable:
10
+ @property
11
+ def has_config(self) -> bool:
12
+ return self.config_path is not None
13
+
14
+ def __init__(self, config_path: Optional[str] = None):
15
+ self.config_path = config_path
16
+ if self.has_config:
17
+ if not file_exists(self.config_path):
18
+ raise FileNotFoundError(f"Can't find config file {self.config_path}")
19
+
20
+
21
+ class HasOptionalExecutable:
22
+ PYTHON: str = "python" if get_os() == OSType.WINDOWS else "python3"
23
+
24
+ @property
25
+ def use_executable(self) -> bool:
26
+ return self.executable_path is not None
27
+
28
+ def __init__(self, name, executable_path: Optional[str] = None) -> None:
29
+ self.name = name
30
+ self.executable_path = executable_path
31
+ if self.use_executable:
32
+ if not file_exists(self.executable_path):
33
+ raise FileNotFoundError(f"Executable not found {self.executable_path}")
34
+
35
+ def get_executable(self, use_system_interpreter: bool = False) -> str:
36
+ if self.use_executable:
37
+ return cast(str, self.executable_path)
38
+
39
+ p = self.PYTHON
40
+ if use_system_interpreter:
41
+ p = sys.executable
42
+ return f"{p} -m {self.name}"
43
+
44
+
45
+ from typing import Optional, Union, List
46
+ from abc import abstractmethod
47
+
48
+
49
+ class QualityAssuranceRunner(Configurable, HasOptionalExecutable):
50
+ """
51
+ QualityAssuranceRunner is an abstract base class that handles the execution of quality assurance
52
+ processes. It extends Configurable and HasOptionalExecutable to incorporate configuration and
53
+ optional executable handling functionalities.
54
+
55
+ :param name: The name of the QA runner.
56
+ :param bound: The bound representing acceptable limits, either as a string or a Bound object.
57
+ :param target: The target to be tested, optional.
58
+ :param configuration_path: The path to the configuration file, optional.
59
+ :param executable_path: The path to the executable, optional.
60
+
61
+ Attributes:
62
+ bound (Bound): The bound object that represents the acceptable limits for the QA process.
63
+ target (Optional[str]): The target to be tested.
64
+ """
65
+
66
+ def __init__(
67
+ self, *,
68
+ name: str,
69
+ bound: Union[str, Bound],
70
+ target: Optional[str] = None,
71
+ configuration_path: Optional[str] = None,
72
+ executable_path: Optional[str] = None
73
+ ) -> None:
74
+ """
75
+ Initializes the QualityAssuranceRunner with the given parameters.
76
+
77
+ :param name: The name of the QA runner.
78
+ :param bound: The bound representing acceptable limits, either as a string or a Bound object.
79
+ :param target: The target to be tested, optional.
80
+ :param configuration_path: The path to the configuration file, optional.
81
+ :param executable_path: The path to the executable, optional.
82
+ """
83
+ Configurable.__init__(self, configuration_path)
84
+ HasOptionalExecutable.__init__(self, name, executable_path)
85
+ self.bound: Bound = bound if isinstance(bound, Bound) else Bound.from_string(bound)
86
+ self.target = target
87
+
88
+ @abstractmethod
89
+ def _build_command(self, target: str, use_system_interpreter: bool = False) -> str:
90
+ """
91
+ Builds the command to be executed for the QA process.
92
+
93
+ :param target: The target to be tested.
94
+ :param use_system_interpreter: Whether to use the system interpreter, default is False.
95
+ :return: The command to be executed as a string.
96
+ """
97
+
98
+ @abstractmethod
99
+ def _install_dependencies(self, base: LayeredCommand) -> None:
100
+ """
101
+ Installs the necessary dependencies for the QA process.
102
+
103
+ :param base: The base LayeredCommand object for executing commands.
104
+ """
105
+
106
+ def _pre_command(self) -> None:
107
+ """
108
+ Hook method to be executed before running the main command.
109
+ Can be overridden by subclasses.
110
+ """
111
+ pass
112
+
113
+ def _post_command(self) -> None:
114
+ """
115
+ Hook method to be executed after running the main command.
116
+ Can be overridden by subclasses.
117
+ """
118
+ pass
119
+
120
+ def run(self, target: str, executor: LayeredCommand, *, verbose: bool = True, # type: ignore
121
+ use_system_interpreter: bool = False, print_func, env_name: str) -> None:
122
+ """
123
+ Runs the QA process on the specified target.
124
+
125
+ :param target: The target to be tested.
126
+ :param executor: The executor object to run the command.
127
+ :param verbose: Whether to output verbose logs, default is True.
128
+ :param use_system_interpreter: Whether to use the system interpreter, default is False.
129
+ :param print_func: The function to use for printing output.
130
+ :param env_name: The name of the environment in which the QA runner is executed.
131
+ """
132
+ from quickpub.proxy import os_system # pylint: disable=import-error
133
+ from quickpub.enforcers import exit_if # pylint: disable=import-error
134
+ # =====================================
135
+ # IMPORTANT: need to explicitly override it here
136
+ executor._executor = os_system # pylint: disable=protected-access
137
+ # =====================================
138
+ command = self._build_command(target, use_system_interpreter)
139
+ self._pre_command()
140
+ try:
141
+ ret, out, err = executor(command, command_raise_on_fail=False)
142
+ score = self._calculate_score(ret, "".join(out + err).splitlines(), verbose=verbose)
143
+ exit_if(not self.bound.compare_against(score),
144
+ f"On env '{env_name}' runner '{self.__class__.__name__}' failed to pass its defined bound. Got a score of {score} but expected {self.bound}",
145
+ verbose=verbose, err_func=print_func)
146
+ except Exception as e:
147
+ raise RuntimeError(
148
+ f"On env {env_name}, failed to run {self.__class__.__name__}. Try running manually:\n{executor._build_command(command)}") from e
149
+ finally:
150
+ self._post_command()
151
+
152
+ @abstractmethod
153
+ def _calculate_score(self, ret: int, command_output: List[str], *, verbose: bool = False) -> float:
154
+ """
155
+ Calculates the score based on the command's return code and output.
156
+
157
+ :param ret: The return code of the executed command.
158
+ :param command_output: The output of the command as a list of strings.
159
+ :param verbose: Whether to output verbose logs, default is False.
160
+ :return: The calculated score as a float.
161
+ """
162
+ ...
163
+
164
+
165
+ __all__ = [
166
+ "QualityAssuranceRunner"
167
+ ]
@@ -3,7 +3,7 @@ from abc import abstractmethod
3
3
  from .quickpub_strategy import QuickpubStrategy
4
4
 
5
5
 
6
- class UploadStrategy(QuickpubStrategy):
6
+ class UploadTarget(QuickpubStrategy):
7
7
  def __init__(self, verbose: bool = True) -> None:
8
8
  self.verbose = verbose
9
9
 
@@ -12,5 +12,5 @@ class UploadStrategy(QuickpubStrategy):
12
12
 
13
13
 
14
14
  __all__ = [
15
- 'UploadStrategy',
15
+ 'UploadTarget',
16
16
  ]
@@ -22,7 +22,7 @@ class Dependency:
22
22
  splits = s.split(op)
23
23
  if len(splits) == 2:
24
24
  return Dependency(splits[0], op, Version.from_str(splits[-1])) # type:ignore
25
- raise ValueError("Invalid 'Dependency' format")
25
+ return Dependency(s, ">=", Version(0, 0, 0))
26
26
 
27
27
  def __str__(self) -> str:
28
28
  if self.ver == Version(0, 0, 0):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quickpub
3
- Version: 1.0.2
3
+ Version: 1.0.3
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
@@ -34,35 +34,38 @@ Requires-Python: >=3.8.0
34
34
  Description-Content-Type: text/markdown
35
35
  License-File: LICENSE
36
36
 
37
- # quickpub V0.8.3
37
+ # quickpub V1.0.3
38
38
  **Tested python versions**: `3.8.0`, `3.9.0`, `3.10.13`,
39
39
 
40
40
  Example usage of how this package was published
41
41
  ```python
42
- from quickpub import publish, AdditionalConfiguration, MypyRunner, PylintRunner, UnittestRunner
42
+ from quickpub import publish, MypyRunner, PylintRunner, UnittestRunner, CondaPythonProvider, \
43
+ PypircUploadTarget, SetuptoolsBuildSchema, GithubUploadTarget
43
44
 
44
45
 
45
46
  def main() -> None:
46
47
  publish(
47
48
  name="quickpub",
48
- version="0.8.0",
49
+ version="1.0.3",
49
50
  author="danielnachumdev",
50
51
  author_email="danielnachumdev@gmail.com",
51
52
  description="A python package to quickly configure and publish a new package",
52
53
  homepage="https://github.com/danielnachumdev/quickpub",
53
- dependencies=["twine", "danielutils"],
54
- min_python="3.9.19",
55
- config=AdditionalConfiguration(
56
- runners=[
57
- MypyRunner(bound="<15"),
58
- PylintRunner(bound=">=0.8"),
59
- UnittestRunner(bound=">=0.8"),
60
- ]
61
- )
54
+ build_schemas=[SetuptoolsBuildSchema()],
55
+ upload_targets=[PypircUploadTarget(), GithubUploadTarget()],
56
+ python_interpreter_provider=CondaPythonProvider(["base", "390", "380"]),
57
+ quality_assurance_runners=[
58
+ MypyRunner(bound="<=15", configuration_path="./mypy.ini"),
59
+ PylintRunner(bound=">=0.8", configuration_path="./.pylintrc"),
60
+ UnittestRunner(bound=">=0.8"),
61
+ ],
62
+ dependencies=["danielutils>=0.9.90"],
63
+ min_python="3.8.0",
62
64
  )
63
65
 
64
66
 
65
67
  if __name__ == '__main__':
66
68
  main()
67
69
 
70
+
68
71
  ```
@@ -19,21 +19,21 @@ quickpub.egg-info/dependency_links.txt
19
19
  quickpub.egg-info/requires.txt
20
20
  quickpub.egg-info/top_level.txt
21
21
  quickpub/strategies/__init__.py
22
- quickpub/strategies/build_strategy.py
23
- quickpub/strategies/python_version_manager_strategy.py
24
- quickpub/strategies/quality_assurance_strategy.py
22
+ quickpub/strategies/build_schema.py
23
+ quickpub/strategies/python_provider.py
24
+ quickpub/strategies/quality_assurance_runner.py
25
25
  quickpub/strategies/quickpub_strategy.py
26
- quickpub/strategies/upload_strategy.py
26
+ quickpub/strategies/upload_target.py
27
27
  quickpub/strategies/implementations/__init__.py
28
28
  quickpub/strategies/implementations/conda_python_version_manager_strategy.py
29
- quickpub/strategies/implementations/git_upload_strategy.py
30
- quickpub/strategies/implementations/mypy_qa_strategy.py
31
- quickpub/strategies/implementations/pylint_qa_strategy.py
32
- quickpub/strategies/implementations/pypirc_upload_strategy.py
33
- quickpub/strategies/implementations/pytest_qa_strategy.py
34
- quickpub/strategies/implementations/setuptools_build_strategy.py
29
+ quickpub/strategies/implementations/github_upload_target.py
30
+ quickpub/strategies/implementations/mypy_qa_runner.py
31
+ quickpub/strategies/implementations/pylint_qa_runner.py
32
+ quickpub/strategies/implementations/pypirc_upload_target.py
33
+ quickpub/strategies/implementations/pytest_qa_runner.py
34
+ quickpub/strategies/implementations/setuptools_build_schema.py
35
35
  quickpub/strategies/implementations/system_interpreter.py
36
- quickpub/strategies/implementations/unittest_qa_strategy.py
36
+ quickpub/strategies/implementations/unittest_qa_runner.py
37
37
  quickpub/structures/__init__.py
38
38
  quickpub/structures/bound.py
39
39
  quickpub/structures/dependency.py
quickpub-1.0.2/README.md DELETED
@@ -1,32 +0,0 @@
1
- # quickpub V0.8.3
2
- **Tested python versions**: `3.8.0`, `3.9.0`, `3.10.13`,
3
-
4
- Example usage of how this package was published
5
- ```python
6
- from quickpub import publish, AdditionalConfiguration, MypyRunner, PylintRunner, UnittestRunner
7
-
8
-
9
- def main() -> None:
10
- publish(
11
- name="quickpub",
12
- version="0.8.0",
13
- author="danielnachumdev",
14
- author_email="danielnachumdev@gmail.com",
15
- description="A python package to quickly configure and publish a new package",
16
- homepage="https://github.com/danielnachumdev/quickpub",
17
- dependencies=["twine", "danielutils"],
18
- min_python="3.9.19",
19
- config=AdditionalConfiguration(
20
- runners=[
21
- MypyRunner(bound="<15"),
22
- PylintRunner(bound=">=0.8"),
23
- UnittestRunner(bound=">=0.8"),
24
- ]
25
- )
26
- )
27
-
28
-
29
- if __name__ == '__main__':
30
- main()
31
-
32
- ```
@@ -1,6 +0,0 @@
1
- from .implementations import *
2
- from .upload_strategy import *
3
- from .quality_assurance_strategy import *
4
- from .quickpub_strategy import *
5
- from .build_strategy import *
6
- from .python_version_manager_strategy import *
@@ -1,9 +0,0 @@
1
- from .pypirc_upload_strategy import *
2
- from .git_upload_strategy import *
3
- from .setuptools_build_strategy import *
4
- from .mypy_qa_strategy import *
5
- from .pylint_qa_strategy import *
6
- from .pytest_qa_strategy import *
7
- from .unittest_qa_strategy import *
8
- from .conda_python_version_manager_strategy import *
9
- from .system_interpreter import *
@@ -1,98 +0,0 @@
1
- import sys
2
- from abc import abstractmethod
3
- from typing import Union, List, Optional, cast
4
- from danielutils import LayeredCommand, get_os, OSType, file_exists
5
-
6
- from quickpub import Bound
7
-
8
-
9
- class Configurable:
10
- @property
11
- def has_config(self) -> bool:
12
- return self.config_path is not None
13
-
14
- def __init__(self, config_path: Optional[str] = None):
15
- self.config_path = config_path
16
- if self.has_config:
17
- if not file_exists(self.config_path):
18
- raise FileNotFoundError(f"Can't find config file {self.config_path}")
19
-
20
-
21
- class HasOptionalExecutable:
22
- PYTHON: str = "python" if get_os() == OSType.WINDOWS else "python3"
23
-
24
- @property
25
- def use_executable(self) -> bool:
26
- return self.executable_path is not None
27
-
28
- def __init__(self, name, executable_path: Optional[str] = None) -> None:
29
- self.name = name
30
- self.executable_path = executable_path
31
- if self.use_executable:
32
- if not file_exists(self.executable_path):
33
- raise FileNotFoundError(f"Executable not found {self.executable_path}")
34
-
35
- def get_executable(self, use_system_interpreter: bool = False) -> str:
36
- if self.use_executable:
37
- return cast(str, self.executable_path)
38
-
39
- p = self.PYTHON
40
- if use_system_interpreter:
41
- p = sys.executable
42
- return f"{p} -m {self.name}"
43
-
44
-
45
- class QualityAssuranceStrategy(Configurable, HasOptionalExecutable):
46
-
47
- def __init__(self, *, name: str, bound: Union[str, Bound], target: Optional[str] = None,
48
- configuration_path: Optional[str] = None,
49
- executable_path: Optional[str] = None) -> None:
50
- Configurable.__init__(self, configuration_path)
51
- HasOptionalExecutable.__init__(self, name, executable_path)
52
- self.bound: Bound = bound if isinstance(bound, Bound) else Bound.from_string(bound)
53
- self.target = target
54
-
55
- @abstractmethod
56
- def _build_command(self, target: str, use_system_interpreter: bool = False) -> str:
57
- ...
58
-
59
- @abstractmethod
60
- def _install_dependencies(self, base: LayeredCommand) -> None:
61
- ...
62
-
63
- def _pre_command(self) -> None:
64
- pass
65
-
66
- def _post_command(self) -> None:
67
- pass
68
-
69
- def run(self, target: str, executor: LayeredCommand, *_, verbose: bool = True, # type: ignore
70
- use_system_interpreter: bool = False, raise_on_fail: bool = False, print_func, env_name: str) -> None:
71
- # =====================================
72
- # IMPORTANT: need to explicitly override it here
73
- from quickpub.proxy import os_system
74
- from quickpub.enforcers import exit_if
75
- executor._executor = os_system
76
- # =====================================
77
- command = self._build_command(target, use_system_interpreter)
78
- self._pre_command()
79
- try:
80
- ret, out, err = executor(command, command_raise_on_fail=False)
81
- score = self._calculate_score(ret, "".join(out + err).splitlines(), verbose=verbose)
82
- exit_if(not self.bound.compare_against(score),
83
- f"On env '{env_name}' runner '{self.__class__.__name__}' failed to pass it's defined bound. Got a score of {score} but expected {self.bound}",
84
- verbose=verbose, err_func=print_func)
85
- except Exception as e:
86
- raise RuntimeError(
87
- f"On env {env_name}, failed to run {self.__class__.__name__}. Try running manually:\n{executor._build_command(command)}") from e
88
- finally:
89
- self._post_command()
90
-
91
- @abstractmethod
92
- def _calculate_score(self, ret: int, command_output: List[str], *, verbose: bool = False) -> float:
93
- ...
94
-
95
-
96
- __all__ = [
97
- "QualityAssuranceStrategy"
98
- ]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes