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 |