Commit Graph

3 Commits

Author SHA1 Message Date
Peter Hutterer d436869a89 Remove directories created by ninja install
Introduce a DirMaker class that disassembles the path up to '/' and stores all
directories in a list. That list is in creation order and pre-existing
directories are ignored, i.e. creating the two paths
'/usr/share/foo/bar/baz' and '/usr/share/foo/bar/boo' is stored as
    [ '/usr/share/foo',
      '/usr/share/foo/bar',
      '/usr/share/foo/bar/baz',
      '/usr/share/foo/bar/boo' ]
This is on the assumption that /usr/share already existed.

After all files have been installed, the list of created directories is
appended in reverse order to the install log. The uninstall script then
triggers rmdir on all directories.

If a custom install script drops files into the directories, removing those
will fail. This matches the current expectation, see the existing warning
"Remember that files created by custom scripts have not been removed."

Unfortunately, this makes the behavior on uninstall inconsistent. Assuming a
non-existing prefix,
        ninja install && ninja uninstall
removes all traces of the install.
However,
        ninja install && ninja install && ninja uninstall
removes the files only, not the directories as they already existed.

This could be fixed by just unconditionally removing any (emtpy) directories
that we drop files into, at the risk of removing system directories if empty.
For example, one could imagine /etc/foo.conf.d/ to be removed in that case if
it is empty.

https://github.com/mesonbuild/meson/issues/2032
2017-08-01 11:40:28 +01:00
Dylan Baker a8173630ea Don't use len() to test emptiness vs not emptiness
Meson has a common pattern of using 'if len(foo) == 0:' or
'if len(foo) != 0:', however, this is a common anti-pattern in python.
Instead tests for emptiness/non-emptiness should be done with a simple
'if foo:' or 'if not foo:'

Consider the following:
>>> import timeit
>>> timeit.timeit('if len([]) == 0: pass')
0.10730923599840025
>>> timeit.timeit('if not []: pass')
0.030033907998586074
>>> timeit.timeit('if len(['a', 'b', 'c', 'd']) == 0: pass')
0.1154778649979562
>>> timeit.timeit("if not ['a', 'b', 'c', 'd']: pass")
0.08259823200205574
>>> timeit.timeit('if len("") == 0: pass')
0.089759664999292
>>> timeit.timeit('if not "": pass')
0.02340641999762738
>>> timeit.timeit('if len("foo") == 0: pass')
0.08848102600313723
>>> timeit.timeit('if not "foo": pass')
0.04032287199879647

And for the one additional case of 'if len(foo.strip()) == 0', which can
be replaced with 'if not foo.isspace()'
>>> timeit.timeit('if len("   ".strip()) == 0: pass')
0.15294511600222904
>>> timeit.timeit('if "   ".isspace(): pass')
0.09413968399894657
>>> timeit.timeit('if len("   abc".strip()) == 0: pass')
0.2023209120015963
>>> timeit.timeit('if "   abc".isspace(): pass')
0.09571301700270851

In other words, it's always a win to not use len(), when you don't
actually want to check the length.
2017-05-02 21:57:26 +03:00
Jussi Pakkanen 0a14ad63de Add simple uninstall target. Closes #753. 2016-12-31 13:55:55 +02:00