quickpub 1.0.1__tar.gz → 1.0.2__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 (53) hide show
  1. {quickpub-1.0.1/quickpub.egg-info → quickpub-1.0.2}/PKG-INFO +1 -1
  2. {quickpub-1.0.1 → quickpub-1.0.2}/pyproject.toml +1 -1
  3. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/__init__.py +1 -2
  4. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/__main__.py +76 -55
  5. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/enforcers.py +2 -2
  6. quickpub-1.0.2/quickpub/functions.py +72 -0
  7. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/qa.py +32 -21
  8. quickpub-1.0.2/quickpub/strategies/__init__.py +6 -0
  9. quickpub-1.0.2/quickpub/strategies/build_strategy.py +16 -0
  10. quickpub-1.0.2/quickpub/strategies/implementations/__init__.py +9 -0
  11. quickpub-1.0.1/quickpub/managers/implementations/conda.py → quickpub-1.0.2/quickpub/strategies/implementations/conda_python_version_manager_strategy.py +4 -4
  12. quickpub-1.0.2/quickpub/strategies/implementations/git_upload_strategy.py +26 -0
  13. quickpub-1.0.1/quickpub/runnables/implementations/mypy.py → quickpub-1.0.2/quickpub/strategies/implementations/mypy_qa_strategy.py +4 -4
  14. quickpub-1.0.1/quickpub/runnables/implementations/pylint.py → quickpub-1.0.2/quickpub/strategies/implementations/pylint_qa_strategy.py +4 -4
  15. quickpub-1.0.2/quickpub/strategies/implementations/pypirc_upload_strategy.py +44 -0
  16. quickpub-1.0.2/quickpub/strategies/implementations/pytest_qa_strategy.py +1 -0
  17. quickpub-1.0.2/quickpub/strategies/implementations/setuptools_build_strategy.py +21 -0
  18. {quickpub-1.0.1/quickpub/managers → quickpub-1.0.2/quickpub/strategies}/implementations/system_interpreter.py +3 -3
  19. quickpub-1.0.1/quickpub/runnables/implementations/unittest.py → quickpub-1.0.2/quickpub/strategies/implementations/unittest_qa_strategy.py +3 -3
  20. quickpub-1.0.1/quickpub/managers/python_manager.py → quickpub-1.0.2/quickpub/strategies/python_version_manager_strategy.py +4 -3
  21. quickpub-1.0.1/quickpub/runnables/base_runner.py → quickpub-1.0.2/quickpub/strategies/quality_assurance_strategy.py +44 -11
  22. quickpub-1.0.2/quickpub/strategies/quickpub_strategy.py +10 -0
  23. quickpub-1.0.2/quickpub/strategies/upload_strategy.py +16 -0
  24. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/structures/__init__.py +0 -1
  25. {quickpub-1.0.1 → quickpub-1.0.2/quickpub.egg-info}/PKG-INFO +1 -1
  26. quickpub-1.0.2/quickpub.egg-info/SOURCES.txt +40 -0
  27. quickpub-1.0.1/quickpub/functions.py +0 -209
  28. quickpub-1.0.1/quickpub/managers/__init__.py +0 -2
  29. quickpub-1.0.1/quickpub/managers/implementations/__init__.py +0 -2
  30. quickpub-1.0.1/quickpub/runnables/__init__.py +0 -2
  31. quickpub-1.0.1/quickpub/runnables/configurable.py +0 -20
  32. quickpub-1.0.1/quickpub/runnables/has_optional_executable.py +0 -32
  33. quickpub-1.0.1/quickpub/runnables/implementations/__init__.py +0 -4
  34. quickpub-1.0.1/quickpub/runnables/implementations/pytest.py +0 -2
  35. quickpub-1.0.1/quickpub/runnables/runnable.py +0 -11
  36. quickpub-1.0.1/quickpub/structures/additional_configuration.py +0 -15
  37. quickpub-1.0.1/quickpub.egg-info/SOURCES.txt +0 -40
  38. {quickpub-1.0.1 → quickpub-1.0.2}/LICENSE +0 -0
  39. {quickpub-1.0.1 → quickpub-1.0.2}/MANIFEST.in +0 -0
  40. {quickpub-1.0.1 → quickpub-1.0.2}/README.md +0 -0
  41. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/classifiers.py +0 -0
  42. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/files.py +0 -0
  43. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/proxy.py +0 -0
  44. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/py.typed +0 -0
  45. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/structures/bound.py +0 -0
  46. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/structures/dependency.py +0 -0
  47. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/structures/version.py +0 -0
  48. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub/validators.py +0 -0
  49. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub.egg-info/dependency_links.txt +0 -0
  50. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub.egg-info/requires.txt +0 -0
  51. {quickpub-1.0.1 → quickpub-1.0.2}/quickpub.egg-info/top_level.txt +0 -0
  52. {quickpub-1.0.1 → quickpub-1.0.2}/setup.cfg +0 -0
  53. {quickpub-1.0.1 → quickpub-1.0.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quickpub
3
- Version: 1.0.1
3
+ Version: 1.0.2
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quickpub"
7
- version = "1.0.1"
7
+ version = "1.0.2"
8
8
  authors = [
9
9
  { name = "danielnachumdev", email = "danielnachumdev@gmail.com" },
10
10
  ]
@@ -1,4 +1,3 @@
1
1
  from .structures import *
2
- from .runnables import *
3
- from .managers import *
2
+ from .strategies import *
4
3
  from .__main__ import publish
@@ -1,11 +1,12 @@
1
1
  import argparse
2
- from typing import Optional, Union, List
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
7
  from .validators import validate_version, validate_python_version, validate_keywords, validate_dependencies, \
6
8
  validate_source
7
- from .functions import build, upload, commit
8
- from .structures import Version, AdditionalConfiguration, Dependency
9
+ from .structures import Version, Dependency
9
10
  from .files import create_toml, create_setup, create_manifest
10
11
  from .classifiers import *
11
12
  from .enforcers import enforce_local_correct_version, enforce_pypirc_exists, exit_if, enforce_remote_correct_version
@@ -19,6 +20,12 @@ def publish(
19
20
  author_email: str,
20
21
  description: str,
21
22
  homepage: str,
23
+
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(),
28
+
22
29
  explicit_src_folder_path: Optional[str] = None,
23
30
  version: Optional[Union[Version, str]] = None,
24
31
  readme_file_path: str = "./README.md",
@@ -28,25 +35,35 @@ def publish(
28
35
 
29
36
  keywords: Optional[List[str]] = None,
30
37
  dependencies: Optional[List[Union[str, Dependency]]] = None,
31
- config: Optional[AdditionalConfiguration] = None
38
+ demo: bool = False,
39
+
40
+ config: Optional[Any] = None,
32
41
  ) -> None:
33
- """The main function of this package. will do all the heavy lifting in order for you to publish your package.
34
-
35
- Args:
36
- name (str): The name of the package
37
- author (str): The name of the author
38
- author_email (str): The email of the author
39
- description (str): A short description for the package
40
- homepage (str): The homepage for the package. URL to the github repo is a good option.
41
- explicit_src_folder_path (Optional[Path], optional): The path to the source code of the package. if None defaults to CWD/<name>
42
- version (Optional[Union[Version, str]], optional): The version to create the new distribution. if None defaults to 0.0.1
43
- readme_file_path (Path, optional): The path to the readme file. Defaults to "./README.md".
44
- license_file_path (Path, optional): The path to the license file . Defaults to "./LICENSE".
45
- 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.
46
- keywords (Optional[list[str]], optional): A list of keywords to describe areas of interests of this package. Defaults to None.
47
- dependencies (Optional[list[str]], optional): A list of the dependencies for this package. Defaults to None.
48
- config (Optional[Config], optional): reserved for future use. Defaults to None.
49
- """
42
+ """The main function for publishing a package. It performs all necessary steps to prepare and publish the package.
43
+
44
+ :param name: The name of the package.
45
+ :param author: The name of the author.
46
+ :param author_email: The email of the author.
47
+ :param description: A short description of the package.
48
+ :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().
53
+ :param explicit_src_folder_path: The path to the source code of the package. Defaults to the current working directory/<name>.
54
+ :param version: The version for the new distribution. Defaults to "0.0.1".
55
+ :param readme_file_path: The path to the README file. Defaults to "./README.md".
56
+ :param license_file_path: The path to the license file. Defaults to "./LICENSE".
57
+ :param min_python: The minimum Python version required for the package. Defaults to the Python version running this script.
58
+ :param keywords: A list of keywords describing areas of interest for the package. Defaults to None.
59
+ :param dependencies: A list of dependencies for the package. Defaults to None.
60
+ :param demo: Whether to perform checks without making any changes. Defaults to False.
61
+ :param config: Reserved for future use. Defaults to None.
62
+
63
+ Returns:
64
+ None
65
+ """
66
+
50
67
  enforce_pypirc_exists()
51
68
  explicit_src_folder_path = validate_source(name, explicit_src_folder_path)
52
69
  if explicit_src_folder_path != f"./{name}":
@@ -55,16 +72,27 @@ def publish(
55
72
  exit_if(not file_exists(readme_file_path), f"Could not find readme file at {readme_file_path}")
56
73
  exit_if(not file_exists(license_file_path), f"Could not find license file at {license_file_path}")
57
74
  version = validate_version(version)
58
- enforce_local_correct_version(name, version)
75
+ if not demo:
76
+ enforce_local_correct_version(name, version)
59
77
  min_python = validate_python_version(min_python) # type:ignore
60
78
  keywords = validate_keywords(keywords)
61
79
  validated_dependencies: List[Dependency] = validate_dependencies(dependencies)
62
80
  enforce_remote_correct_version(name, version)
63
81
 
82
+ if quality_assurance_strategies is None:
83
+ quality_assurance_strategies = []
64
84
  try:
65
- if not qa(name, config, explicit_src_folder_path, validated_dependencies):
66
- error(
67
- f"quickpub.publish exited early as '{name}' did not pass quality assurance step, see above logs to pass this step.")
85
+ res = qa(
86
+ python_version_manager_strategy,
87
+ quality_assurance_strategies,
88
+ name,
89
+ explicit_src_folder_path,
90
+ validated_dependencies
91
+ )
92
+ if not res:
93
+ error(f"quickpub.publish exited early as '{name}' "
94
+ "did not pass quality assurance step, see above "
95
+ "logs to pass this step.")
68
96
  raise SystemExit(1)
69
97
  except SystemExit as e:
70
98
  raise e
@@ -93,15 +121,11 @@ def publish(
93
121
  min_python=min_python
94
122
  )
95
123
  create_manifest(name=name)
96
-
97
- build()
98
- upload(
99
- name=name,
100
- version=version
101
- )
102
- commit(
103
- version=version
104
- )
124
+ if not demo:
125
+ for build_strategy in build_strategies:
126
+ build_strategy.execute_strategy()
127
+ for upload_strategy in upload_strategies:
128
+ upload_strategy.execute_strategy(name=name, version=version)
105
129
 
106
130
 
107
131
  def parse_args():
@@ -124,25 +148,22 @@ def parse_args():
124
148
  return parser.parse_args()
125
149
 
126
150
 
127
- def main():
128
- args = parse_args()
129
-
130
- publish(
131
- name=args.name,
132
- author=args.author,
133
- author_email=args.author_email,
134
- description=args.description,
135
- homepage=args.homepage,
136
- explicit_src_folder_path=args.explicit_src_folder_path,
137
- version=args.version,
138
- readme_file_path=args.readme_file_path,
139
- license_file_path=args.license_file_path,
140
- min_python=args.min_python,
141
- keywords=args.keywords,
142
- dependencies=args.dependencies,
143
- config=args.config
144
- )
145
-
146
-
147
151
  if __name__ == '__main__':
148
- main()
152
+ print("CLI is not currently supported")
153
+ # args = parse_args()
154
+ #
155
+ # publish(
156
+ # name=args.name,
157
+ # author=args.author,
158
+ # author_email=args.author_email,
159
+ # description=args.description,
160
+ # homepage=args.homepage,
161
+ # explicit_src_folder_path=args.explicit_src_folder_path,
162
+ # version=args.version,
163
+ # readme_file_path=args.readme_file_path,
164
+ # license_file_path=args.license_file_path,
165
+ # min_python=args.min_python,
166
+ # keywords=args.keywords,
167
+ # dependencies=args.dependencies,
168
+ # config=args.config
169
+ # )
@@ -21,7 +21,7 @@ def _remove_suffix(s: str, suffix: str) -> str:
21
21
  :return: modified string
22
22
  """
23
23
  if get_python_version() >= (3, 9):
24
- return s.removesuffix(suffix)
24
+ return s.removesuffix(suffix) # type:ignore
25
25
  return _remove_prefix(s[::-1], suffix[::-1])[::-1]
26
26
 
27
27
 
@@ -33,7 +33,7 @@ def _remove_prefix(s: str, prefix: str) -> str:
33
33
  :return:
34
34
  """
35
35
  if get_python_version() >= (3, 9):
36
- return s.removeprefix(prefix)
36
+ return s.removeprefix(prefix) # type:ignore
37
37
 
38
38
  if s.startswith(prefix):
39
39
  return s[len(prefix):]
@@ -0,0 +1,72 @@
1
+ import sys
2
+ from typing import Optional, Literal
3
+ from danielutils import info
4
+
5
+ from .enforcers import exit_if
6
+ from .structures import Version
7
+ import quickpub.proxy
8
+
9
+
10
+ def build(
11
+ *,
12
+ verbose: bool = True
13
+ ) -> None:
14
+ if verbose:
15
+ info("Creating new distribution...")
16
+ ret, stdout, stderr = quickpub.proxy.cm("python", "setup.py", "sdist")
17
+ exit_if(
18
+ ret != 0,
19
+ stderr.decode(encoding="utf8")
20
+ )
21
+
22
+
23
+ def upload(
24
+ *,
25
+ name: str,
26
+ version: Version,
27
+ verbose: bool = True
28
+ ) -> None:
29
+ if verbose:
30
+ info("Uploading")
31
+ ret, stdout, stderr = quickpub.proxy.cm("twine", "upload", "--config-file", ".pypirc",
32
+ f"dist/{name}-{version}.tar.gz")
33
+ exit_if(
34
+ ret != 0,
35
+ f"Failed uploading the package to pypi. Try running the following command manually:\n\ttwine upload --config-file .pypirc dist/{name}-{version}.tar.gz"
36
+ )
37
+
38
+
39
+ def commit(
40
+ *,
41
+ version: Version,
42
+ verbose: bool = True
43
+ ) -> None:
44
+ if verbose:
45
+ info("Git")
46
+ info("\tStaging")
47
+ ret, stdout, stderr = quickpub.proxy.cm("git add .")
48
+ exit_if(
49
+ ret != 0,
50
+ stderr.decode(encoding="utf8")
51
+ )
52
+ if verbose:
53
+ info("\tCommitting")
54
+ ret, stdout, stderr = quickpub.proxy.cm(f"git commit -m \"updated to version {version}\"")
55
+ exit_if(
56
+ ret != 0,
57
+ stderr.decode(encoding="utf8")
58
+ )
59
+ if verbose:
60
+ info("\tPushing")
61
+ ret, stdout, stderr = quickpub.proxy.cm("git push")
62
+ exit_if(
63
+ ret != 0,
64
+ stderr.decode(encoding="utf8")
65
+ )
66
+
67
+
68
+ __all__ = [
69
+ "build",
70
+ "upload",
71
+ "commit",
72
+ ]
@@ -4,8 +4,9 @@ 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 .managers import PythonManager # pylint: disable=relative-beyond-top-level
8
- from .structures import AdditionalConfiguration, Dependency, Version, Bound # pylint: disable=relative-beyond-top-level
7
+ from quickpub import QualityAssuranceStrategy
8
+ from .strategies import PythonVersionManagerStrategy # pylint: disable=relative-beyond-top-level
9
+ from .structures import Dependency, Version, Bound # pylint: disable=relative-beyond-top-level
9
10
  from .enforcers import exit_if # pylint: disable=relative-beyond-top-level
10
11
 
11
12
  try:
@@ -53,7 +54,7 @@ def global_import_sanity_check(package_name: str, executor: LayeredCommand, is_s
53
54
  VERSION_REGEX: re.Pattern = re.compile(r"^\d+\.\d+\.\d+$")
54
55
 
55
56
 
56
- def validate_dependencies(python_manager: PythonManager, required_dependencies: List[Dependency],
57
+ def validate_dependencies(python_manager: PythonVersionManagerStrategy, required_dependencies: List[Dependency],
57
58
  executor: LayeredCommand,
58
59
  env_name: str, err_print_func: Callable) -> None:
59
60
  """
@@ -92,13 +93,22 @@ def validate_dependencies(python_manager: PythonManager, required_dependencies:
92
93
  err_func=err_print_func)
93
94
 
94
95
 
95
- def create_progress_bar_pool(config, python_manager) -> ProgressBarPool:
96
+ def create_progress_bar_pool(python_version_manager: PythonVersionManagerStrategy,
97
+ quality_assurance_strategies: List[QualityAssuranceStrategy]) -> ProgressBarPool:
96
98
  return ProgressBarPool(
97
99
  AsciiProgressBar,
98
100
  2,
99
101
  individual_options=[
100
- dict(iterator=python_manager, desc="Envs", total=len(python_manager.requested_envs)),
101
- dict(iterator=config.runners or [], desc="Runners", total=len(config.runners or [])),
102
+ dict(
103
+ iterator=python_version_manager,
104
+ desc="Envs",
105
+ total=len(python_version_manager.requested_envs)
106
+ ),
107
+ dict(
108
+ iterator=quality_assurance_strategies or [],
109
+ desc="Runners",
110
+ total=len(quality_assurance_strategies or [])
111
+ ),
102
112
  ]
103
113
  )
104
114
 
@@ -112,18 +122,19 @@ def create_pool_print_error(pool: ProgressBarPool):
112
122
  return func
113
123
 
114
124
 
115
- def qa(package_name: str, config: Optional[AdditionalConfiguration], src_folder_path: Optional[str],
116
- dependencies: list) -> bool:
117
- if config is None:
118
- return True
125
+ def qa(
126
+ python_version_manager: PythonVersionManagerStrategy,
127
+ quality_assurance_strategies: List[QualityAssuranceStrategy],
128
+ package_name: str,
129
+ src_folder_path: Optional[str],
130
+ dependencies: list
131
+ ) -> bool:
132
+ from .strategies import SystemInterpreter
119
133
  result = True
120
- python_manager = config.python_manager
121
- is_system_interpreter: bool = False
122
- if python_manager is None:
123
- from .managers import SystemInterpreter
124
- python_manager = SystemInterpreter()
125
- is_system_interpreter = True
126
- pool = create_progress_bar_pool(config, python_manager)
134
+ if python_version_manager is None:
135
+ python_version_manager = SystemInterpreter()
136
+ is_system_interpreter = isinstance(python_version_manager, SystemInterpreter)
137
+ pool = create_progress_bar_pool(python_version_manager, quality_assurance_strategies)
127
138
  pool_err = create_pool_print_error(pool)
128
139
  with MultiContext(
129
140
  AttrContext(LayeredCommand, 'class_flush_stdout', False),
@@ -137,7 +148,7 @@ def qa(package_name: str, config: Optional[AdditionalConfiguration], src_folder_
137
148
  with executor:
138
149
  executor._prev_instance = base
139
150
  try:
140
- validate_dependencies(python_manager, dependencies, executor, env_name, pool_err)
151
+ validate_dependencies(python_version_manager, dependencies, executor, env_name, pool_err)
141
152
  except SystemExit:
142
153
  result = False
143
154
  continue
@@ -154,7 +165,7 @@ def qa(package_name: str, config: Optional[AdditionalConfiguration], src_folder_
154
165
  src_folder_path,
155
166
  executor,
156
167
  use_system_interpreter=is_system_interpreter,
157
- raise_on_fail=python_manager.exit_on_fail,
168
+ raise_on_fail=python_version_manager.exit_on_fail,
158
169
  print_func=pool_err,
159
170
  env_name=env_name
160
171
  )
@@ -168,8 +179,8 @@ def qa(package_name: str, config: Optional[AdditionalConfiguration], src_folder_
168
179
  f"Failed running '{runner.__class__.__name__}' on env '{env_name}'. "
169
180
  f"Try manually: '{manual_command}'.")
170
181
  pool.write(f"\tCaused by '{e.__cause__ or e}'")
171
- if python_manager.exit_on_fail:
172
- raise e
182
+ if python_version_manager.exit_on_fail:
183
+ raise RuntimeError() from e
173
184
  return result
174
185
 
175
186
 
@@ -0,0 +1,6 @@
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 *
@@ -0,0 +1,16 @@
1
+ from abc import abstractmethod
2
+
3
+ from .quickpub_strategy import QuickpubStrategy
4
+
5
+
6
+ class BuildStrategy(QuickpubStrategy):
7
+ def __init__(self, verbose: bool = True) -> None:
8
+ self.verbose = verbose
9
+
10
+ @abstractmethod
11
+ def execute_strategy(self, *args, **kwargs) -> None: ...
12
+
13
+
14
+ __all__ = [
15
+ "BuildStrategy"
16
+ ]
@@ -0,0 +1,9 @@
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,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_manager import PythonManager
4
+ from ..python_version_manager_strategy import PythonVersionManagerStrategy
5
5
 
6
6
 
7
- class CondaPythonManager(PythonManager):
7
+ class CondaPythonVersionManagerStrategy(PythonVersionManagerStrategy):
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
- PythonManager.__init__(self, requested_envs=env_names, explicit_versions=[], exit_on_fail=True)
12
+ PythonVersionManagerStrategy.__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 CondaPythonManager(PythonManager):
33
33
 
34
34
 
35
35
  __all__ = [
36
- 'CondaPythonManager',
36
+ 'CondaPythonVersionManagerStrategy',
37
37
  ]
@@ -0,0 +1,26 @@
1
+ from danielutils import info
2
+
3
+ from ..upload_strategy import UploadStrategy
4
+
5
+ class GitUploadStrategy(UploadStrategy):
6
+ def execute_strategy(self, version: str, **kwargs) -> None:
7
+ from quickpub.proxy import cm
8
+ from quickpub.enforcers import exit_if
9
+ if self.verbose:
10
+ info("Git")
11
+ info("\tStaging")
12
+ ret, stdout, stderr = cm("git add .")
13
+ exit_if(ret != 0, stderr.decode(encoding="utf8"))
14
+ if self.verbose:
15
+ info("\tCommitting")
16
+ ret, stdout, stderr = cm(f"git commit -m \"updated to version {version}\"")
17
+ exit_if(ret != 0, stderr.decode(encoding="utf8"))
18
+ if self.verbose:
19
+ info("\tPushing")
20
+ ret, stdout, stderr = cm("git push")
21
+ exit_if(ret != 0, stderr.decode(encoding="utf8"))
22
+
23
+
24
+ __all__ = [
25
+ "GitUploadStrategy",
26
+ ]
@@ -3,10 +3,10 @@ from typing import Optional, List
3
3
 
4
4
  from danielutils import LayeredCommand
5
5
 
6
- from ..base_runner import BaseRunner
6
+ from ..quality_assurance_strategy import QualityAssuranceStrategy
7
7
 
8
8
 
9
- class MypyRunner(BaseRunner):
9
+ class MypyRunner(QualityAssuranceStrategy):
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(BaseRunner):
23
23
 
24
24
  def __init__(self, bound: str = "<15", configuration_path: Optional[str] = None,
25
25
  executable_path: Optional[str] = None) -> None:
26
- BaseRunner.__init__(self, name="mypy", bound=bound, configuration_path=configuration_path,
27
- executable_path=executable_path)
26
+ QualityAssuranceStrategy.__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 ..base_runner import BaseRunner
6
+ from strategies.quality_assurance_strategy import QualityAssuranceStrategy
7
7
 
8
8
 
9
- class PylintRunner(BaseRunner):
9
+ class PylintRunner(QualityAssuranceStrategy):
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(BaseRunner):
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
- BaseRunner.__init__(self, name="pylint", bound=bound, configuration_path=configuration_path,
19
- executable_path=executable_path)
18
+ QualityAssuranceStrategy.__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()
@@ -0,0 +1,44 @@
1
+ import re
2
+
3
+ from danielutils import file_exists, info
4
+
5
+ from ..upload_strategy import UploadStrategy
6
+
7
+
8
+ class PypircUploadStrategy(UploadStrategy):
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")
11
+
12
+ def execute_strategy(self, *, name: str, version: str, **kwargs) -> None:
13
+ from quickpub.proxy import cm
14
+ from quickpub.enforcers import exit_if
15
+ self._validate_file_exists()
16
+ self._validate_file_contents()
17
+ if self.verbose:
18
+ info("Uploading")
19
+ ret, stdout, stderr = cm("twine", "upload", "--config-file", ".pypirc",
20
+ f"dist/{name}-{version}.tar.gz")
21
+ exit_if(
22
+ ret != 0,
23
+ f"Failed uploading the package to pypi. Try running the following command manually:\n\ttwine upload --config-file .pypirc dist/{name}-{version}.tar.gz"
24
+ )
25
+
26
+ def _validate_file_exists(self) -> None:
27
+ if not file_exists(self.pypirc_file_path):
28
+ raise RuntimeError(f"{self.__class__.__name__} can't find pypirc file at '{self.pypirc_file_path}'")
29
+
30
+ def _validate_file_contents(self) -> None:
31
+ with open(self.pypirc_file_path, "r", encoding="utf8") as f:
32
+ text = f.read()
33
+ if not self.REGEX_PATTERN.match(text):
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}")
36
+
37
+ def __init__(self, pypirc_file_path: str = "./.pypirc", verbose: bool = False) -> None:
38
+ super().__init__(verbose)
39
+ self.pypirc_file_path = pypirc_file_path
40
+
41
+
42
+ __all__ = [
43
+ "PypircUploadStrategy"
44
+ ]
@@ -0,0 +1,21 @@
1
+ from danielutils import info
2
+
3
+ from ..build_strategy import BuildStrategy
4
+
5
+
6
+ class SetuptoolsBuildStrategy(BuildStrategy):
7
+ def execute_strategy(self, *args, **kwargs) -> None:
8
+ from quickpub.proxy import cm
9
+ from quickpub.enforcers import exit_if
10
+ if self.verbose:
11
+ info("Creating new distribution...")
12
+ ret, stdout, stderr = cm("python", "setup.py", "sdist")
13
+ exit_if(
14
+ ret != 0,
15
+ stderr.decode(encoding="utf8")
16
+ )
17
+
18
+
19
+ __all__ = [
20
+ "SetuptoolsBuildStrategy",
21
+ ]
@@ -3,15 +3,15 @@ from typing import Set, Tuple, Iterator
3
3
 
4
4
  from danielutils import LayeredCommand
5
5
 
6
- from .. import PythonManager
6
+ from ..python_version_manager_strategy import PythonVersionManagerStrategy
7
7
 
8
8
 
9
- class SystemInterpreter(PythonManager):
9
+ class SystemInterpreter(PythonVersionManagerStrategy):
10
10
  def get_python_executable_name(self) -> str:
11
11
  return sys.executable
12
12
 
13
13
  def __init__(self) -> None:
14
- PythonManager.__init__(self, requested_envs=["system"], explicit_versions=[], exit_on_fail=True)
14
+ PythonVersionManagerStrategy.__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(""))])
@@ -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 ..base_runner import BaseRunner
6
+ from strategies.quality_assurance_strategy import QualityAssuranceStrategy
7
7
 
8
8
 
9
- class UnittestRunner(BaseRunner):
9
+ class UnittestRunner(QualityAssuranceStrategy):
10
10
  def _install_dependencies(self, base: LayeredCommand) -> None:
11
11
  return None
12
12
 
@@ -23,7 +23,7 @@ class UnittestRunner(BaseRunner):
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
- BaseRunner.__init__(self, name="unittest", bound=bound, target=target)
26
+ QualityAssuranceStrategy.__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: