Skip to content

Instantly share code, notes, and snippets.

@evlanov-alex
Created December 22, 2018 12:40
Show Gist options
  • Select an option

  • Save evlanov-alex/dd4d11229ced9f1b7600250ef57d225f to your computer and use it in GitHub Desktop.

Select an option

Save evlanov-alex/dd4d11229ced9f1b7600250ef57d225f to your computer and use it in GitHub Desktop.
My utils for managing django project (migrations and packages)
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