[master 2/15] Make a "Path" object that handles separate fs root for us.
vathpela
installerbot-noreply at redhat.com
Wed Oct 28 17:43:37 UTC 2015
From: Peter Jones <pjones at redhat.com>
This also makes path joining simpler, and automagically normalizes
slashes reasonably.
Signed-off-by: Peter Jones <pjones at redhat.com>
---
blivet/util.py | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/blivet/util.py b/blivet/util.py
index 344e582..9ca58ab 100644
--- a/blivet/util.py
+++ b/blivet/util.py
@@ -1,6 +1,7 @@
import copy
import errno
import functools
+import glob
import itertools
import os
import shutil
@@ -32,6 +33,114 @@
# this will get set to anaconda's program_log_lock in enable_installer_mode
program_log_lock = Lock()
+class Path(str):
+ """ Path(path, root=None) provides a filesystem path object, which
+ automatically normalizes slashes, assumes appends are what you
+ always hoped os.path.join() was (but with out the weird slash
+ games), and can easily handle paths with a root directory other
+ than /
+ """
+ _root = None
+ _path = None
+ def __new__(cls, path, root=None, *args, **kwds):
+ obj = str.__new__(cls, path, *args, **kwds)
+ obj._path = path
+ obj._root = None
+ if root is not None:
+ obj.newroot(str(root))
+ return obj
+
+ @property
+ def ondisk(self):
+ """ Path.ondisk evaluates as the real filesystem path of the path,
+ including the path's root in the data.
+ """
+ return normalize_path_slashes(Path(self.root) + Path(self.path))
+
+ @property
+ def path(self):
+ return self._path
+
+ @property
+ def normpath(self):
+ return Path(os.path.normpath(str(self.path)), root=self.root)
+
+ @property
+ def realpath(self):
+ rp = os.path.realpath(self.ondisk)
+ return Path(rp, root=self.root)
+
+ @property
+ def root(self):
+ return self._root
+
+ def newroot(self, newroot=None):
+ """ Change the root directory of this Path """
+ if newroot is None:
+ self._root = None
+ else:
+ self._root = normalize_path_slashes(newroot)
+ if self.startswith(self._root):
+ path = self._path[len(self._root):]
+ self._path = normalize_path_slashes(path)
+ return self
+
+ def __str__(self):
+ return str(self.path)
+
+ def __repr__(self):
+ return repr(str(self.path))
+
+ def __getitem__(self, idx):
+ ret = str(self)
+ return ret.__getitem__(idx)
+
+ def __add__(self, other):
+ if isinstance(other, Path):
+ if other.root != None and other.root != "/":
+ if self.root == None:
+ self._root = other.root
+ elif other.root != self.root:
+ raise ValueError("roots <%s> and <%s> don't match." %
+ (self.root, other.root))
+ path = "%s/%s" % (self.path, other.path)
+ else:
+ path = "%s/%s" % (self.path, other)
+ path = normalize_path_slashes(path)
+ return Path(path, root=self.root)
+
+ def __eq__(self, other):
+ if isinstance(other, Path):
+ return self.path == other.path
+ else:
+ return self.path == str(other)
+
+ def __lt__(self, other):
+ if isinstance(other, Path):
+ return self.path < other.path
+ else:
+ return self.path < str(other)
+
+ def __gt__(self, other):
+ if isinstance(other, Path):
+ return self.path > other.path
+ else:
+ return self.path > str(other)
+
+ def startswith(self, other):
+ return self._path.startswith(str(other))
+
+ def glob(self):
+ """ Similar to glob.glob(), except it takes the Path's root into
+ account when globbing and returns path objects with the same
+ root, so you don't have to think about that part.
+ """
+ for g in glob.glob(self.ondisk):
+ yield Path(g, root=self.root)
+
+ def __hash__(self):
+ return self._path.__hash__()
+
def _run_program(argv, root='/', stdin=None, env_prune=None, stderr_to_stdout=False, binary_output=False):
if env_prune is None:
env_prune = []
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/a16a3ce071460f2e34d1ef164ac736e0b22f63da
More information about the anaconda-patches
mailing list