from setuptools import setup, Command
from setuptools.command.install import install as orig_install
from distutils.command.build import build as orig_build

import fastentrypoints          # noqa: F401, import for side-effects!

from subprocess import call
import logging
from os import path, listdir
from glob import glob


# language files
po_source_folder = 'lang'
mo_build_prefix = path.join('build', 'locale')
mo_install_prefix = path.join('share', 'locale')

# completion files
comp_source_folder = 'completions'
comp_install_prefix = path.join('share', 'zsh', 'site-functions')

# menu icons
theme_base = path.join('share', 'icons', 'hicolor')
icon_names = ['mount', 'unmount', 'lock', 'unlock', 'eject', 'detach']


class build(orig_build):
    """Subclass build command to add a subcommand for building .mo files."""
    sub_commands = orig_build.sub_commands + [('build_mo', None)]


class build_mo(Command):

    """Create machine specific translation files (for i18n via gettext)."""

    description = 'Compile .po files into .mo files'

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        for po_filename in glob(path.join(po_source_folder, '*.po')):
            lang = path.splitext(path.split(po_filename)[1])[0]
            mo_filename = path.join(mo_build_prefix, lang,
                                    'LC_MESSAGES', 'udiskie.mo')
            self.mkpath(path.dirname(mo_filename))
            self.make_file(
                po_filename,
                mo_filename,
                self.make_mo,
                [po_filename, mo_filename])

    def make_mo(self, po_filename, mo_filename):
        """Create a machine object (.mo) from a portable object (.po) file."""
        try:
            call(['msgfmt', po_filename, '-o', mo_filename])
        except OSError as e:
            # ignore failures since i18n support is optional:
            logging.warning(e)


# NOTE: we want the install logic from *distutils* rather than the one from
# *setuptools*. distutils does NOT automatically install dependencies. On the
# other hand, setuptools fails to invoke the build commands properly before
# trying to install and it puts the data files in the egg directory (we want
# them in `sys.prefix` or similar).
# NOTE: Subclassing the setuptools install command alters its behaviour to use
# the distutils code. This is due to some really odd call-context checks in
# the setuptools command.
# NOTE: We need to subclass the setuptools install command rather than the
# distutils command to make installing with pip from the source distribution
# work.
class install(orig_install):

    """Custom install command used to update the gtk icon cache."""

    def run(self):
        """
        Perform old-style (distutils) install, then update GTK icon cache.

        Extends ``distutils.command.install.install.run``.
        """
        orig_install.run(self)
        try:
            call(['gtk-update-icon-cache', theme_base])
        except OSError as e:
            # ignore failures since the tray icon is an optional component:
            logging.warning(e)


data_files = [
    (path.join(mo_install_prefix, lang, 'LC_MESSAGES'),
     [path.join(mo_build_prefix, lang, 'LC_MESSAGES', 'udiskie.mo')])
    for po_filename in glob(path.join(po_source_folder, '*.po'))
    for lang in [path.splitext(path.split(po_filename)[1])[0]]
]

data_files += [
    (path.join(theme_base, 'scalable', 'actions'), [
        path.join('icons', 'scalable', 'actions',
                  'udiskie-{0}.svg'.format(icon_name))
        for icon_name in icon_names]),
    (comp_install_prefix, [
        path.join(comp_source_folder, cmd)
        for cmd in listdir(comp_source_folder)
    ]),
]

setup(
    cmdclass={
        'install': install,
        'build': build,
        'build_mo': build_mo,
    },
    data_files=data_files,
)

@@ -289,17 +289,8 @@
 path
-, listdir
 %0Afro
@@ -640,79 +640,8 @@
 r')%0A
-icon_names = %5B'mount', 'unmount', 'lock', 'unlock', 'eject', 'detach'%5D%0A
 %0A%0Acl
@@ -3411,27 +3411,27 @@
 tions'),
- %5B
 %0A     
-   
+glob(
 path.joi
@@ -3463,34 +3463,16 @@
 ctions',
-%0A                 
  'udiski
@@ -3477,72 +3477,16 @@
 kie-
-%7B0%7D
+*
 .svg'
-.format(icon_name))%0A        for icon_name in icon_names%5D
+))
 ),%0A 
@@ -3513,19 +3513,19 @@
 fix,
- %5B
 %0A     
-   
+glob(
 path
@@ -3554,65 +3554,14 @@
 er, 
-cmd)%0A        for cmd in listdir(comp_source_folder)%0A    %5D
+'_*'))
 ),%0A%5D

Simplify using glob