From a9b31113b76bde3debc696c1ce71aa7dd594faa3 Mon Sep 17 00:00:00 2001 From: Will Szumski Date: Mon, 7 Jan 2019 15:34:45 +0000 Subject: [PATCH] Do not globally replace path prefix If a subdirectory contained the source prefix in it's name, this was replaced globally e.g using share/ansible = ansible/*, with the following directory structure: ansible/roles/kolla-ansible/test would result in the files being installed as follows: share/ansible/roles/kolla-share/test whereas we expected: share/ansible/roles/kolla-ansible/test This patch changes the behavior so that only the first occurance is replaced. Change-Id: I0aab845315dab0aaccd5f67725d2ebcf0fd08aef Fixes-Bug: 1810804 --- pbr/hooks/files.py | 8 +++++-- pbr/tests/test_files.py | 21 +++++++++++++++++++ ...f-src-prefix-in-glob-eb850b94ca96993e.yaml | 9 ++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 releasenotes/notes/fix-global-replace-of-src-prefix-in-glob-eb850b94ca96993e.yaml diff --git a/pbr/hooks/files.py b/pbr/hooks/files.py index 48bf9e31..750ac32c 100644 --- a/pbr/hooks/files.py +++ b/pbr/hooks/files.py @@ -58,8 +58,12 @@ class FilesConfig(base.BaseConfig): if not target.endswith(os.path.sep): target += os.path.sep for (dirpath, dirnames, fnames) in os.walk(source_prefix): - finished.append( - "%s = " % dirpath.replace(source_prefix, target)) + # As source_prefix is always matched, using replace with a + # a limit of one is always going to replace the path prefix + # and not accidentally replace some text in the middle of + # the path + new_prefix = dirpath.replace(source_prefix, target, 1) + finished.append("%s = " % new_prefix) finished.extend( [" %s" % os.path.join(dirpath, f) for f in fnames]) else: diff --git a/pbr/tests/test_files.py b/pbr/tests/test_files.py index e60b6ca7..ed67f7bc 100644 --- a/pbr/tests/test_files.py +++ b/pbr/tests/test_files.py @@ -35,15 +35,20 @@ class FilesConfigTest(base.BaseTestCase): ]) self.useFixture(pkg_fixture) pkg_etc = os.path.join(pkg_fixture.base, 'etc') + pkg_ansible = os.path.join(pkg_fixture.base, 'ansible', + 'kolla-ansible', 'test') pkg_sub = os.path.join(pkg_etc, 'sub') subpackage = os.path.join( pkg_fixture.base, 'fake_package', 'subpackage') os.makedirs(pkg_sub) os.makedirs(subpackage) + os.makedirs(pkg_ansible) with open(os.path.join(pkg_etc, "foo"), 'w') as foo_file: foo_file.write("Foo Data") with open(os.path.join(pkg_sub, "bar"), 'w') as foo_file: foo_file.write("Bar Data") + with open(os.path.join(pkg_ansible, "baz"), 'w') as baz_file: + baz_file.write("Baz Data") with open(os.path.join(subpackage, "__init__.py"), 'w') as foo_file: foo_file.write("# empty") @@ -76,3 +81,19 @@ class FilesConfigTest(base.BaseTestCase): self.assertIn( '\netc/pbr/ = \n etc/foo\netc/pbr/sub = \n etc/sub/bar', config['files']['data_files']) + + def test_data_files_globbing_source_prefix_in_directory_name(self): + # We want to test that the string, "docs", is not replaced in a + # subdirectory name, "sub-docs" + config = dict( + files=dict( + data_files="\n share/ansible = ansible/*" + ) + ) + files.FilesConfig(config, 'fake_package').run() + self.assertIn( + '\nshare/ansible/ = ' + '\nshare/ansible/kolla-ansible = ' + '\nshare/ansible/kolla-ansible/test = ' + '\n ansible/kolla-ansible/test/baz', + config['files']['data_files']) diff --git a/releasenotes/notes/fix-global-replace-of-src-prefix-in-glob-eb850b94ca96993e.yaml b/releasenotes/notes/fix-global-replace-of-src-prefix-in-glob-eb850b94ca96993e.yaml new file mode 100644 index 00000000..b2895aa1 --- /dev/null +++ b/releasenotes/notes/fix-global-replace-of-src-prefix-in-glob-eb850b94ca96993e.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Fixes a bug where the directory names of items specified in ``data_files`` + could be renamed if the source prefix glob was contained within the + directory name. See `bug 1810804 + `_ for details. For more + information on ``data_files``, see the `distutils documentation + `_.