From 3ce09d0d725add6210edbb7cf864e4883631d76f Mon Sep 17 00:00:00 2001 From: Mateusz Masiarz Date: Wed, 27 Sep 2023 16:15:56 +0200 Subject: [PATCH 1/4] Function to check if there are correct permissions (cherry picked from commit 92d097fa39a752f3bd6b1b5c31bcbf098ac645b0) --- src/sinol_make/helpers/cache.py | 14 ++++++++++++++ src/sinol_make/util.py | 32 ++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/sinol_make/helpers/cache.py b/src/sinol_make/helpers/cache.py index 24128b7f..d062fb5e 100644 --- a/src/sinol_make/helpers/cache.py +++ b/src/sinol_make/helpers/cache.py @@ -117,3 +117,17 @@ def remove_results_if_contest_type_changed(contest_type): if package_util.check_if_contest_type_changed(contest_type): remove_results_cache() package_util.save_contest_type_to_cache(contest_type) + + +def check_can_access_cache(): + """ + Checks if user can access cache. + """ + try: + os.makedirs(paths.get_cache_path(), exist_ok=True) + with open(paths.get_cache_path("test"), "w") as f: + f.write("test") + os.unlink(paths.get_cache_path("test")) + except PermissionError: + util.exit_with_error("You don't have permission to access the `.cache/` directory. " + "`sinol-make` needs to be able to write to this directory.") diff --git a/src/sinol_make/util.py b/src/sinol_make/util.py index a0fb7173..6aabf743 100644 --- a/src/sinol_make/util.py +++ b/src/sinol_make/util.py @@ -10,6 +10,7 @@ import sinol_make from sinol_make.contest_types import get_contest_type +from sinol_make.helpers import paths, cache from sinol_make.structs.status_structs import Status @@ -54,6 +55,7 @@ def exit_if_not_package(): """ if not find_and_chdir_package(): exit_with_error('You are not in a package directory (couldn\'t find config.yml in current directory).') + cache.check_can_access_cache() def save_config(config): @@ -141,16 +143,21 @@ def check_for_updates(current_version) -> Union[str, None]: thread.start() version_file = data_dir.joinpath("version") - if version_file.is_file(): + try: version = version_file.read_text() + except PermissionError: try: - if compare_versions(current_version, version) == -1: - return version - else: - return None - except ValueError: # If the version file is corrupted, we just ignore it. + with open(paths.get_cache_path("sinol_make_version"), "r") as f: + version = f.read() + except (FileNotFoundError, PermissionError): return None - else: + + try: + if compare_versions(current_version, version) == -1: + return version + else: + return None + except ValueError: # If the version file is corrupted, we just ignore it. return None @@ -173,7 +180,16 @@ def check_version(): latest_version = data["info"]["version"] version_file = importlib.files("sinol_make").joinpath("data/version") - version_file.write_text(latest_version) + try: + version_file.write_text(latest_version) + except PermissionError: + if find_and_chdir_package(): + try: + os.makedirs(paths.get_cache_path(), exist_ok=True) + with open(paths.get_cache_path("sinol_make_version"), "w") as f: + f.write(latest_version) + except PermissionError: + pass def compare_versions(version_a, version_b): From 940ee78aa4a921e947e5a79c4bf0af6f03c2f62c Mon Sep 17 00:00:00 2001 From: Mateusz Masiarz Date: Wed, 27 Sep 2023 16:16:14 +0200 Subject: [PATCH 2/4] Add tests (cherry picked from commit 70061c2e934a770443774c0d89ead02bc3f39038) --- tests/test_util.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/test_util.py b/tests/test_util.py index ac674140..7054fa57 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -11,6 +11,7 @@ import yaml from sinol_make import util, configure_parsers +from sinol_make.helpers import paths from tests import util as test_util from tests.fixtures import create_package from tests.commands.run import util as run_util @@ -79,6 +80,9 @@ def test_check_version(**kwargs): version_file = data_dir.joinpath("version") if not data_dir.is_dir(): data_dir.mkdir() + data_dir.chmod(0o777) + if version_file.is_file(): + version_file.unlink() # Test correct request mocker.get("https://pypi.python.org/pypi/sinol-make/json", json={"info": {"version": "1.0.0"}}) @@ -97,6 +101,37 @@ def test_check_version(**kwargs): util.check_version() assert not version_file.is_file() + with tempfile.TemporaryDirectory() as tmpdir: + os.chdir(tmpdir) + with open("config.yml", "w") as config_file: + config_file.write("") + + # No permission to write + version_file.write_text("0.0.0") + version_file.chmod(0o000) + mocker.get("https://pypi.python.org/pypi/sinol-make/json", json={"info": {"version": "1.0.0"}}) + util.check_version() + assert version_file.is_file() + version_file.chmod(0o777) + assert version_file.read_text() == "0.0.0" + assert os.path.exists(paths.get_cache_path("sinol_make_version")) + with open(paths.get_cache_path("sinol_make_version"), "r") as f: + assert f.read() == "1.0.0" + + # No permission to write to cache and data dir + with open(paths.get_cache_path("sinol_make_version"), "w") as f: + f.write("0.0.0") + os.chmod(paths.get_cache_path("sinol_make_version"), 0o000) + os.chmod(paths.get_cache_path(), 0o000) + os.chmod(data_dir, 0o000) + version_file.chmod(0o000) + mocker.get("https://pypi.python.org/pypi/sinol-make/json", json={"info": {"version": "1.0.0"}}) + util.check_version() + os.chmod(data_dir, 0o777) + version_file.chmod(0o777) + assert version_file.is_file() + assert version_file.read_text() == "0.0.0" + @pytest.mark.parametrize("create_package", [test_util.get_simple_package_path()], indirect=True) def test_version_change(create_package): From f19102b79ebbbcab4259895bf4aa3ed5af34ebba Mon Sep 17 00:00:00 2001 From: Mateusz Masiarz Date: Wed, 27 Sep 2023 16:30:35 +0200 Subject: [PATCH 3/4] Fix --- src/sinol_make/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sinol_make/util.py b/src/sinol_make/util.py index 6aabf743..1bfbb3aa 100644 --- a/src/sinol_make/util.py +++ b/src/sinol_make/util.py @@ -145,7 +145,7 @@ def check_for_updates(current_version) -> Union[str, None]: try: version = version_file.read_text() - except PermissionError: + except (PermissionError, FileNotFoundError): try: with open(paths.get_cache_path("sinol_make_version"), "r") as f: version = f.read() From a49b7e1f80ee300ad1a7acdff2c896a54b6632d1 Mon Sep 17 00:00:00 2001 From: Mateusz Masiarz Date: Thu, 5 Oct 2023 16:26:14 +0200 Subject: [PATCH 4/4] Change tests --- tests/test_util.py | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/tests/test_util.py b/tests/test_util.py index 7054fa57..6a767068 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -101,37 +101,6 @@ def test_check_version(**kwargs): util.check_version() assert not version_file.is_file() - with tempfile.TemporaryDirectory() as tmpdir: - os.chdir(tmpdir) - with open("config.yml", "w") as config_file: - config_file.write("") - - # No permission to write - version_file.write_text("0.0.0") - version_file.chmod(0o000) - mocker.get("https://pypi.python.org/pypi/sinol-make/json", json={"info": {"version": "1.0.0"}}) - util.check_version() - assert version_file.is_file() - version_file.chmod(0o777) - assert version_file.read_text() == "0.0.0" - assert os.path.exists(paths.get_cache_path("sinol_make_version")) - with open(paths.get_cache_path("sinol_make_version"), "r") as f: - assert f.read() == "1.0.0" - - # No permission to write to cache and data dir - with open(paths.get_cache_path("sinol_make_version"), "w") as f: - f.write("0.0.0") - os.chmod(paths.get_cache_path("sinol_make_version"), 0o000) - os.chmod(paths.get_cache_path(), 0o000) - os.chmod(data_dir, 0o000) - version_file.chmod(0o000) - mocker.get("https://pypi.python.org/pypi/sinol-make/json", json={"info": {"version": "1.0.0"}}) - util.check_version() - os.chmod(data_dir, 0o777) - version_file.chmod(0o777) - assert version_file.is_file() - assert version_file.read_text() == "0.0.0" - @pytest.mark.parametrize("create_package", [test_util.get_simple_package_path()], indirect=True) def test_version_change(create_package):