From 1b2bab09cdfb3a0d0f514cfe586e823477c3f7c2 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Sun, 4 Aug 2024 23:27:55 -0400 Subject: [PATCH 01/13] refactor `batch_upload` function --- reserver/reserver_obj.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 28d93fa..8bfa131 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -31,7 +31,7 @@ def __init__(self, api_token, test_pypi=False): self.password = api_token self.test_pypi = test_pypi - def batch_upload(self, *names): + def batch_upload(self, names, user_params_path=None): """ Upload batch of package names to PyPI. @@ -40,13 +40,25 @@ def batch_upload(self, *names): :return: Number of successfully reserved packages """ reserved_successfully = 0 - for name in names: - if isinstance(name, list): - reserved_successfully += self.batch_upload(*name) - else: - is_reserved = self.upload(name) - if is_reserved: + if user_params_path == None: + for name in names: + if self.upload(name): + reserved_successfully += 1 + elif isinstance(user_params_path, str): + for name in names: + if self.upload(name, user_parameters=user_params_path): reserved_successfully += 1 + elif isinstance(user_params_path, list): + if len(user_params_path) == 1: + for name in names: + if self.upload(name, user_parameters=user_params_path[0]): + reserved_successfully += 1 + elif len(user_params_path) == len(names): + for index, name in enumerate(names): + if self.upload(name, user_parameters=user_params_path[index]): + reserved_successfully += 1 + else: + raise ReserverBaseError(UNEQUAL_PARAM_NAME_LENGTH_ERROR) return reserved_successfully def upload(self, package_name, user_parameters=None): From 23b2204fb019fac489ffb102007dcc6e44b69722 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Sun, 4 Aug 2024 23:28:22 -0400 Subject: [PATCH 02/13] add `read_json` to upload function to read user defined params from json file --- reserver/reserver_obj.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 8bfa131..3dd2ef9 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -75,6 +75,9 @@ def upload(self, package_name, user_parameters=None): print("This package already exists in PyPI.") return False + if user_parameters != None: + user_parameters = read_json(user_parameters) + generate_template_setup_py(package_name, user_parameters) environ["TWINE_USERNAME"] = self.username From 0b86b94a2683f5b960510ecafbec7dcf00bb4c90 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Sun, 4 Aug 2024 23:30:36 -0400 Subject: [PATCH 03/13] docstrings fulfilled --- reserver/reserver_obj.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index 3dd2ef9..f504ca7 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -4,10 +4,11 @@ from re import sub from sys import executable from os import environ, path, getcwd, remove -from .util import has_named_parameter, remove_dir +from .reserver_errors import ReserverBaseError from subprocess import check_output, CalledProcessError +from .util import has_named_parameter, remove_dir, read_json from .reserver_func import does_package_exist, generate_template_setup_py - +from .reserver_param import INVALID_INPUT_USER_PARAM, UNEQUAL_PARAM_NAME_LENGTH_ERROR class PyPIUploader: """ @@ -36,7 +37,9 @@ def batch_upload(self, names, user_params_path=None): Upload batch of package names to PyPI. :param names: packages' names - :type names: vararg + :type names: list + :param user_params_path: path to user-defined packages' parameters + :type user_params_path: None | str | list :return: Number of successfully reserved packages """ reserved_successfully = 0 @@ -67,8 +70,8 @@ def upload(self, package_name, user_parameters=None): :param package_name: package name :type package_name: str - :param user_parameters: user-customized package parameters - :type user_parameters: dict + :param user_parameters: path to the .json file containing user-defined package parameters + :type user_parameters: str :return: True if the package is successfully reserved, False otherwise """ if does_package_exist(package_name, self.test_pypi): From 1f98e5473bb6447c62a0597d88222eab860e523d Mon Sep 17 00:00:00 2001 From: AHReccese Date: Sun, 4 Aug 2024 23:30:44 -0400 Subject: [PATCH 04/13] add new error messages --- reserver/reserver_param.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/reserver/reserver_param.py b/reserver/reserver_param.py index cc35afe..d507738 100644 --- a/reserver/reserver_param.py +++ b/reserver/reserver_param.py @@ -21,4 +21,9 @@ "url": r'^(http|https)://[a-zA-Z0-9.-_]+\.[a-zA-Z]{2,}(/\S*)?$', } INVALID_PACKAGE_PARAMETER_NAME_ERROR = "Given parameter doesn't exist among the supported user allowed parameters." -INVALID_PACKAGE_PARAMETER_VALUE_ERROR = "Invalid value for {parameter} that should be a valid {regex}" \ No newline at end of file +INVALID_PACKAGE_PARAMETER_VALUE_ERROR = "Invalid value for {parameter} that should be a valid {regex}" +INVALID_CONFIG_FILE_NAME_ERROR = "Given file name for user-defined setup.py params is not a string." +PARAM_FILE_DOES_NOT_EXIST_ERROR = "Given file doesn't exist." +INVALID_INPUT_USER_PARAM = "Invalid input for user params." +UNEQUAL_PARAM_NAME_LENGTH_ERROR = "You should pass either one single file path to be used for setup.py parameters \ +or per each package name, there should be a specific dedicated file path." \ No newline at end of file From 3b7569c0322657aa1851e8b9dacaa8dc6ed7af10 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Sun, 4 Aug 2024 23:31:20 -0400 Subject: [PATCH 05/13] add test for batch upload with custom param file per package name --- tests/config.json | 9 +++++++++ tests/config2.json | 9 +++++++++ tests/test_reserver.py | 8 ++++++++ 3 files changed, 26 insertions(+) create mode 100644 tests/config.json create mode 100644 tests/config2.json diff --git a/tests/config.json b/tests/config.json new file mode 100644 index 0000000..ce3036b --- /dev/null +++ b/tests/config.json @@ -0,0 +1,9 @@ +{ + "description": "[config] This name has been reserved using Reserver", + "author": "[config] Development Team", + "author_email": "configtest@test.com", + "url": "https://configurl.com", + "download_url": "https://configdownload_url.com", + "source": "https://configgithub.com/source", + "license": "[config] MIT" +} \ No newline at end of file diff --git a/tests/config2.json b/tests/config2.json new file mode 100644 index 0000000..8118716 --- /dev/null +++ b/tests/config2.json @@ -0,0 +1,9 @@ +{ + "description": "[config2] This name has been reserved using Reserver", + "author": "[config2] Development Team", + "author_email": "config2test@test.com", + "url": "https://config2url.com", + "download_url": "https://config2download_url.com", + "source": "https://config2github.com/source", + "license": "[config2] MIT" +} \ No newline at end of file diff --git a/tests/test_reserver.py b/tests/test_reserver.py index c860aee..4520890 100644 --- a/tests/test_reserver.py +++ b/tests/test_reserver.py @@ -36,3 +36,11 @@ def test_module_conflict(): # try to reserve a name which conflicts with the module name of a previously taken package (the taken package itself has a different name, but it's module name has conflict)." uploader = PyPIUploader(pypi_token, test_pypi=False) assert uploader.upload("freeze") == False + +def test_batch_upload(): + # try to reserve two non taken package names with per package custom setup.py parameters + uploader = PyPIUploader(test_pypi_token, True) + assert uploader.batch_upload( + [get_random_name(), get_random_name() + get_random_name()], + ["config.json", "config2.json"] + ) == 2 \ No newline at end of file From 041f5cad6ed93a3818371f1e00d186897b745045 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Sun, 4 Aug 2024 23:31:38 -0400 Subject: [PATCH 06/13] `read_json` function in `util.py` --- reserver/util.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/reserver/util.py b/reserver/util.py index f84d4ff..5fd45b6 100644 --- a/reserver/util.py +++ b/reserver/util.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- """utility module.""" -from inspect import signature import os +import json import shutil - +from inspect import signature +from .reserver_errors import ReserverBaseError +from .reserver_param import INVALID_CONFIG_FILE_NAME_ERROR, PARAM_FILE_DOES_NOT_EXIST_ERROR def has_named_parameter(func, param_name): """ @@ -32,3 +34,22 @@ def remove_dir(dirpath): """ if os.path.exists(dirpath) and os.path.isdir(dirpath): shutil.rmtree(dirpath) + + +def read_json(file_name): + """ + Read the json file and return the python obj of it. + + :param file_name: name of the .json file + :type file_name: str + :return: obj + """ + if not isinstance(file_name, str): + raise ReserverBaseError(INVALID_CONFIG_FILE_NAME_ERROR) + if ".json" not in file_name: + file_name = file_name + ".json" + if os.path.isfile(file_name): + config_file = open(file_name) + return json.load(config_file) + else: + raise ReserverBaseError(PARAM_FILE_DOES_NOT_EXIST_ERROR) \ No newline at end of file From 61683f47f07fa041b1c27101a4d5fd04d0bf9d7f Mon Sep 17 00:00:00 2001 From: AHReccese Date: Sun, 4 Aug 2024 23:33:55 -0400 Subject: [PATCH 07/13] comment batch test to prevent namespace squatting --- tests/test_reserver.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/test_reserver.py b/tests/test_reserver.py index 4520890..dc6b24f 100644 --- a/tests/test_reserver.py +++ b/tests/test_reserver.py @@ -39,8 +39,9 @@ def test_module_conflict(): def test_batch_upload(): # try to reserve two non taken package names with per package custom setup.py parameters - uploader = PyPIUploader(test_pypi_token, True) - assert uploader.batch_upload( - [get_random_name(), get_random_name() + get_random_name()], - ["config.json", "config2.json"] - ) == 2 \ No newline at end of file + # uploader = PyPIUploader(test_pypi_token, True) + # assert uploader.batch_upload( + # [get_random_name(), get_random_name() + get_random_name()], + # ["config.json", "config2.json"] + # ) == 2 + assert True == True \ No newline at end of file From ae4c26cce869cc5514326786a5c3f9983b64f726 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Mon, 5 Aug 2024 14:35:14 -0400 Subject: [PATCH 08/13] fix batch upload syntax --- tests/test_reserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_reserver.py b/tests/test_reserver.py index dc6b24f..ae702bb 100644 --- a/tests/test_reserver.py +++ b/tests/test_reserver.py @@ -18,7 +18,7 @@ def test_standard_module_conflict(): def test_batch_packages_names(): # test batch of package names uploader = PyPIUploader(test_pypi_token, test_pypi=True) - assert uploader.batch_upload("numpy", "scikit-learn") == 0 + assert uploader.batch_upload(["numpy", "scikit-learn"]) == 0 def test_valid_package_invalid_credentials(): # test not reserved name -> wrong credentials From 409026256b54623a374ba1d54d615121a16f50a8 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Mon, 5 Aug 2024 15:52:26 -0400 Subject: [PATCH 09/13] CHANGELOG.md updated --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73a16ce..4b01edb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added - more testcases in conflict cases +- `batch_upload` tests +- `read_json` method in `util.py` ### Changed - `upload` method in `reserver_obj.py` +- `batch_upload` method `reserver_obj.py` ## [0.2] - 2024-06-17 ### Added - `CLI` handler From a2b9707f163eea744ad47c8417ffaf93bba9832f Mon Sep 17 00:00:00 2001 From: AHReccese Date: Mon, 5 Aug 2024 15:55:39 -0400 Subject: [PATCH 10/13] remove unused parameters --- reserver/reserver_obj.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reserver/reserver_obj.py b/reserver/reserver_obj.py index f504ca7..ceb3669 100644 --- a/reserver/reserver_obj.py +++ b/reserver/reserver_obj.py @@ -6,9 +6,9 @@ from os import environ, path, getcwd, remove from .reserver_errors import ReserverBaseError from subprocess import check_output, CalledProcessError +from .reserver_param import UNEQUAL_PARAM_NAME_LENGTH_ERROR from .util import has_named_parameter, remove_dir, read_json from .reserver_func import does_package_exist, generate_template_setup_py -from .reserver_param import INVALID_INPUT_USER_PARAM, UNEQUAL_PARAM_NAME_LENGTH_ERROR class PyPIUploader: """ From 92fad669d1133964ab160bd8380a10d38fa47ea6 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Tue, 6 Aug 2024 09:48:18 -0400 Subject: [PATCH 11/13] error texts updated --- reserver/reserver_param.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reserver/reserver_param.py b/reserver/reserver_param.py index d507738..108af6e 100644 --- a/reserver/reserver_param.py +++ b/reserver/reserver_param.py @@ -22,8 +22,8 @@ } INVALID_PACKAGE_PARAMETER_NAME_ERROR = "Given parameter doesn't exist among the supported user allowed parameters." INVALID_PACKAGE_PARAMETER_VALUE_ERROR = "Invalid value for {parameter} that should be a valid {regex}" -INVALID_CONFIG_FILE_NAME_ERROR = "Given file name for user-defined setup.py params is not a string." +INVALID_CONFIG_FILE_NAME_ERROR = "Given file name for user-defined package params is not a string." PARAM_FILE_DOES_NOT_EXIST_ERROR = "Given file doesn't exist." INVALID_INPUT_USER_PARAM = "Invalid input for user params." -UNEQUAL_PARAM_NAME_LENGTH_ERROR = "You should pass either one single file path to be used for setup.py parameters \ -or per each package name, there should be a specific dedicated file path." \ No newline at end of file +UNEQUAL_PARAM_NAME_LENGTH_ERROR = "You should pass either one single file path to be used for the package parameters \ +or per each package name, there should be a specific dedicated file path." From 345ad48901d785893cae61f5976bfb80456a8ac5 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Tue, 6 Aug 2024 09:48:48 -0400 Subject: [PATCH 12/13] remove ".json" format check --- reserver/util.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/reserver/util.py b/reserver/util.py index 5fd45b6..769e1b1 100644 --- a/reserver/util.py +++ b/reserver/util.py @@ -46,10 +46,8 @@ def read_json(file_name): """ if not isinstance(file_name, str): raise ReserverBaseError(INVALID_CONFIG_FILE_NAME_ERROR) - if ".json" not in file_name: - file_name = file_name + ".json" if os.path.isfile(file_name): config_file = open(file_name) return json.load(config_file) else: - raise ReserverBaseError(PARAM_FILE_DOES_NOT_EXIST_ERROR) \ No newline at end of file + raise ReserverBaseError(PARAM_FILE_DOES_NOT_EXIST_ERROR) From 4496359b4b64feee095dbc8c5dbcce07147b95d0 Mon Sep 17 00:00:00 2001 From: AHReccese Date: Tue, 6 Aug 2024 09:48:56 -0400 Subject: [PATCH 13/13] "\n" added --- tests/test_reserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_reserver.py b/tests/test_reserver.py index ae702bb..b496773 100644 --- a/tests/test_reserver.py +++ b/tests/test_reserver.py @@ -44,4 +44,4 @@ def test_batch_upload(): # [get_random_name(), get_random_name() + get_random_name()], # ["config.json", "config2.json"] # ) == 2 - assert True == True \ No newline at end of file + assert True == True