Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH] bin/doins.py: implement install -p option (bug 642632)
Date: Fri, 29 Dec 2017 20:40:02
Message-Id: 20171229203531.138617-1-zmedico@gentoo.org
1 Bug: https://bugs.gentoo.org/642632
2 ---
3 bin/doins.py | 13 ++++++++++---
4 pym/portage/tests/bin/test_doins.py | 4 ++--
5 2 files changed, 12 insertions(+), 5 deletions(-)
6
7 diff --git a/bin/doins.py b/bin/doins.py
8 index 92e450979..dceffee83 100644
9 --- a/bin/doins.py
10 +++ b/bin/doins.py
11 @@ -107,6 +107,7 @@ def _parse_install_options(
12 parser.add_argument('-g', '--group', default=-1, type=_parse_group)
13 parser.add_argument('-o', '--owner', default=-1, type=_parse_user)
14 parser.add_argument('-m', '--mode', default=0o755, type=_parse_mode)
15 + parser.add_argument('-p', '--preserve-timestamps', action='store_true')
16 split_options = shlex.split(options)
17 namespace, remaining = parser.parse_known_args(split_options)
18 # Because parsing '--mode' option is partially supported. If unknown
19 @@ -168,7 +169,8 @@ class _InsInProcessInstallRunner(object):
20 True on success, otherwise False.
21 """
22 dest = os.path.join(dest_dir, os.path.basename(source))
23 - if not self._is_install_allowed(source, dest):
24 + sstat = os.stat(source)
25 + if not self._is_install_allowed(source, sstat, dest):
26 return False
27
28 # To emulate the `install` command, remove the dest file in
29 @@ -187,6 +189,11 @@ class _InsInProcessInstallRunner(object):
30 movefile._copyxattr(
31 source, dest,
32 exclude=self._xattr_exclude)
33 + if self._parsed_options.preserve_timestamps:
34 + if sys.version_info >= (3, 3):
35 + os.utime(dest, ns=(sstat.st_mtime_ns, sstat.st_mtime_ns))
36 + else:
37 + os.utime(dest, (sstat.st_mtime, sstat.st_mtime))
38 except Exception:
39 logging.exception(
40 'Failed to copy file: '
41 @@ -195,13 +202,14 @@ class _InsInProcessInstallRunner(object):
42 return False
43 return True
44
45 - def _is_install_allowed(self, source, dest):
46 + def _is_install_allowed(self, source, source_stat, dest):
47 """Returns if installing source into dest should work.
48
49 This is to keep compatibility with the `install` command.
50
51 Args:
52 source: path to the source file.
53 + source_stat: stat result for the source file.
54 dest: path to the dest file.
55
56 Returns:
57 @@ -210,7 +218,6 @@ class _InsInProcessInstallRunner(object):
58 # To match `install` command, use stat() for source, while
59 # lstat() for dest. Raise an exception if stat(source) fails,
60 # intentionally.
61 - source_stat = os.stat(source)
62 try:
63 dest_lstat = os.lstat(dest)
64 except OSError as e:
65 diff --git a/pym/portage/tests/bin/test_doins.py b/pym/portage/tests/bin/test_doins.py
66 index 14d7adfa6..dd40abf6e 100644
67 --- a/pym/portage/tests/bin/test_doins.py
68 +++ b/pym/portage/tests/bin/test_doins.py
69 @@ -38,7 +38,7 @@ class DoIns(setup_env.BinTestCase):
70 self.init()
71 try:
72 env = setup_env.env
73 - env['INSOPTIONS'] = '-m0644'
74 + env['INSOPTIONS'] = '-pm0644'
75 with open(os.path.join(env['S'], 'test'), 'w'):
76 pass
77 doins('test')
78 @@ -145,7 +145,7 @@ class DoIns(setup_env.BinTestCase):
79 env = setup_env.env
80 # Use an option which doins.py does not know.
81 # Then, fallback to `install` command is expected.
82 - env['INSOPTIONS'] = '-p'
83 + env['INSOPTIONS'] = '-b'
84 with open(os.path.join(env['S'], 'test'), 'w'):
85 pass
86 doins('test')
87 --
88 2.13.6

Replies