Skip to content

Commit

Permalink
Better UX error for migrations (#7966)
Browse files Browse the repository at this point in the history
* Better UX error for migrations

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* File already exists is not an error

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Print dir path name for makedirs error

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Fix cache attribute

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Run migration test

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Fix expected string

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Improve migration error message

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Filter error message for utils.file.save

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Exclude errno.ENOENT from file errors

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Could not apply chmod on Windows

There is a note on chmod docs:
https://docs.python.org/2.7/library/os.html#os.chmod

"Although Windows supports chmod(), you can only set the file’s
read-only flag with it (via the stat.S_IWRITE and stat.S_IREAD constants
or a corresponding integer value). All other bits are ignored."

However, it works for files, not for folder.

Signed-off-by: Uilian Ries <uilianries@gmail.com>
  • Loading branch information
uilianries committed Oct 29, 2020
1 parent fabef25 commit c7f6749
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
5 changes: 3 additions & 2 deletions conans/migrations.py
Expand Up @@ -32,8 +32,9 @@ def _make_migrations(self, old_version):
def _update_version_file(self):
try:
save(self.file_version_path, str(self.current_version))
except Exception:
raise ConanException("Can't write version file in %s" % self.file_version_path)
except Exception as error:
raise ConanException("Can't write version file in '{}': {}"
.format(self.file_version_path, str(error)))

def _load_old_version(self):
try:
Expand Down
Empty file.
36 changes: 36 additions & 0 deletions conans/test/unittests/client/migrations/test_migrator.py
@@ -0,0 +1,36 @@
# coding=utf-8

import unittest
import os
import platform

from conans.migrations import Migrator
from conans.test.utils.mocks import TestBufferConanOutput
from conans.test.utils.test_files import temp_folder
from conans.errors import ConanMigrationError


class FakeMigrator(Migrator):

def __init__(self, cache_folder, current_version, out):
self.cache_folder = cache_folder
super(FakeMigrator, self).__init__(cache_folder, current_version, out)

def _make_migrations(self, old_version):
pass


class MigratorPermissionTest(unittest.TestCase):

@unittest.skipIf(platform.system() == "Windows", "Can't apply chmod on Windows")
def test_invalid_permission(self):
out = TestBufferConanOutput()
conf_path = temp_folder(False)
os.chmod(conf_path, 0o444)
conf_path = os.path.join(conf_path, "foo")
migrator = FakeMigrator(conf_path, "latest", out)
with self.assertRaises(ConanMigrationError) as error:
migrator.migrate()
self.assertEqual("Can't write version file in '{0}/version.txt': The folder {0} does not "
"exist and could not be created (Permission denied).".format(conf_path),
str(error.exception))
14 changes: 10 additions & 4 deletions conans/util/files.py
Expand Up @@ -187,10 +187,16 @@ def save(path, content, only_if_modified=False, encoding="utf-8"):
only_if_modified: file won't be modified if the content hasn't changed
encoding: target file text encoding
"""
try:
os.makedirs(os.path.dirname(path))
except Exception:
pass
dir_path = os.path.dirname(path)
if not os.path.isdir(dir_path):
try:
os.makedirs(dir_path)
except OSError as error:
if error.errno not in (errno.EEXIST, errno.ENOENT):
raise OSError("The folder {} does not exist and could not be created ({})."
.format(dir_path, error.strerror))
except Exception:
raise

new_content = to_file_bytes(content, encoding)

Expand Down

0 comments on commit c7f6749

Please sign in to comment.