Created
December 22, 2018 12:40
-
-
Save evlanov-alex/dd4d11229ced9f1b7600250ef57d225f to your computer and use it in GitHub Desktop.
My utils for managing django project (migrations and packages)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from abc import ABCMeta, abstractmethod, abstractproperty | |
| import inspect | |
| import pip | |
| import sys | |
| import os | |
| import re | |
| BASE_DIR = os.path.abspath(os.path.dirname(__file__)) | |
| class BaseCommand: | |
| __metaclass__ = ABCMeta | |
| @abstractproperty | |
| def verbose_name(self): | |
| pass | |
| @abstractproperty | |
| def help(self): | |
| pass | |
| @abstractmethod | |
| def run(self): | |
| pass | |
| class Migrations(BaseCommand): | |
| verbose_name = 'migrations' | |
| help = 'Shows all migrations in project' | |
| MIGRATION_RE = re.compile(r'^\d{4}_.+\.py$') | |
| def __init__(self): | |
| self.delete = False | |
| if len(sys.argv) == 3 and sys.argv[-1] == 'delete': | |
| self.delete = True | |
| def _show_migrations_for_directory(self, abspath): | |
| print(os.path.relpath(abspath)) | |
| files = [i for i in os.listdir(abspath) if self.MIGRATION_RE.match(i)] | |
| for f in sorted(files): | |
| print('-- {}'.format(f)) | |
| print('') | |
| def _drop_migrations_for_directory(self, abspath): | |
| for filename in os.listdir(abspath): | |
| if self.MIGRATION_RE.match(filename): | |
| os.remove(os.path.join(abspath, filename)) | |
| def run(self): | |
| migrations_dirs = [] | |
| for root, dirs, files in os.walk(BASE_DIR): | |
| if 'migrations' in dirs: | |
| migrations_dirs.append(os.path.join(root, 'migrations')) | |
| for directory in sorted(migrations_dirs): | |
| if self.delete: | |
| self._drop_migrations_for_directory(directory) | |
| else: | |
| self._show_migrations_for_directory(directory) | |
| class Packages(BaseCommand): | |
| verbose_name = 'packages' | |
| help = 'Compares packages from requirements and installed' | |
| requirements_files = [ | |
| os.path.join(BASE_DIR, 'requirements.txt'), | |
| os.path.join(BASE_DIR, 'requirements_dev.txt') | |
| ] | |
| PACKAGE_RE = re.compile(r'(?P<name>\S+)\s*==\s*(?P<version>\S+)') | |
| def _get_installed_packages(self,): | |
| installed = {i.project_name.lower(): i.version.lower() for i in pip.get_installed_distributions()} | |
| return installed | |
| def _get_required_packages(self): | |
| required = {} | |
| for filename in self.requirements_files: | |
| with open(filename) as f: | |
| for line in f: | |
| matching = self.PACKAGE_RE.match(line) | |
| if matching: | |
| required[matching.group('name').lower()] = matching.group('version').lower() | |
| return required | |
| def run(self): | |
| installed = self._get_installed_packages() | |
| required = self._get_required_packages() | |
| for package, version in required.iteritems(): | |
| installed_version = installed.get(package) | |
| if installed_version: | |
| if installed_version != version: | |
| print('{} -- installed {} instead of {}'.format(package, installed_version, version)) | |
| else: | |
| print('{}=={} -- not installed yet'.format(package, version)) | |
| def main(): | |
| available_commands = {} | |
| current_module = sys.modules[__name__] | |
| for name, cls in inspect.getmembers(current_module, inspect.isclass): | |
| if cls.__module__ == __name__ and cls is not BaseCommand: | |
| available_commands[cls.verbose_name] = cls | |
| if len(sys.argv) < 2: | |
| print('Incorrect args count') | |
| else: | |
| command = sys.argv[1] | |
| if not command in available_commands.keys(): | |
| print('Unknown command. Available commands are: ') | |
| for i in available_commands.values(): | |
| print('{} -- {}'.format(i.verbose_name, i.help)) | |
| else: | |
| command_cls = available_commands[command] | |
| command_cls().run() | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment