Ejemplo n.º 1
0
Archivo: south.py Proyecto: dencold/blt
    def migrate(self, *apps):
        """
        Applies all outstanding deltas to the database.

        Here the south API is a little friendlier and you can apply migrations
        to the entire django project. Or, if you so desire, you can apply only
        to specific apps. Just pass the list as an argument.

        Args:
            apps: list of apps to apply migrations, if none given, will run
                migrations across the entire project

        Usage:
            blt south.migrate [apps]

        Examples:
            blt south.migrate - default, runs all migrations
            blt south.migrate invest payment - runs migrations for invest and
                payment apps
        """
        with cd(self.cfg['django']['DJANGO_ROOT']):
            if not apps:
                local('python manage.py migrate')
            else:
                for app in apps:
                    local('python manage.py migrate %s' % app)
Ejemplo n.º 2
0
    def config(self, action='', *configs):
        """
        Executes a set/get/unset action to the remote heroku config.

        Args:
            action: string config action. either set, get, or unset
            configs: list of configurations

        Usage:
            blt e:[env] heroku.config [set|get|unset] ["Key=Value"]

        Examples:
            blt e:s heroku.config - default lists the current config on staging
            blt e:s heroku.config set - sets *ALL* config defined in beltenv
                configuration file on heroku
            blt e:p heroku.config set "SSL_ENABLED=True" - sets the SSL_ENABLED
                config setting to True in production
            blt e:p heroku.config unset SSL_ENABLED - unsets the SSL_ENABLED
                config setting
        """
        if not action:
            local('heroku config --app %s' % self.cfg['heroku']['app'])
        else:
            if not configs:
                # if we don't have any runtime configs from the commandline,
                # we want to run a list comprehension to convert all of the
                # items in the beltenv configuration dict into a list of
                # "key=value" strings:
                configs = [''.join([k,'=',v])
                    for k,v in self.cfg['heroku']['config'].iteritems()]

            local('heroku config:%s %s --app %s' % (action
                                                    , ' '.join(configs)
                                                    , self.cfg['heroku']['app']))
Ejemplo n.º 3
0
    def push(self, git_arg=''):
        """
        Pushes your local git branch to heroku.

        We handle pushing from a non-master branch for you, just set
        ``git_branch`` in your beltenv configuration.

        Args:
            git_arg: any valid argument to git push (optional)

        Usage:
            blt e:[env] heroku.push [arg]

        Examples:
            blt e:s heroku.push - pushes branch to heroku staging environment
            blt e:s heroku.push force - forces a push to heroku staging
            blt e:p heroku.push verbose - pushes to production in verbose mode
        """
        if git_arg:
            local('git push %s %s:master --%s' % (self.cfg['heroku']['git_remote']
                                                    , self.cfg['heroku']['git_branch']
                                                    , git_arg))
        else:
            local('git push %s %s:master' % (self.cfg['heroku']['git_remote']
                                            , self.cfg['heroku']['git_branch']))
Ejemplo n.º 4
0
    def dump(self, deal_slug, database):
        """
        Dumps a given deal out to a fixture file.

        This makes use of the custom django management command which
        encapsulates the logic to pull out all of the important model data for
        a deal. It uses the passed "database" arg to pull the appropriate
        DATABASE_URL from the bltenv settings. It outputs the fixture to the
        configured BUNDLE_ROOT.

        Args:
            deal_slug: the unique slug for the deal
            database: the database to dump from

        Usage:
            blt bundle.dump (deal_slug) (database)

        Examples:
            blt bundle.dump blumhouse-productions STAGING
        """
        environ["DATABASE_URL"] = self.cfg["bundle"][database]
        fixture_file = self._fixture_file(deal_slug)
        self._prep_bundle_dir(path.split(fixture_file)[0])

        with cd(self.cfg["django"]["DJANGO_ROOT"]):
            local("python manage.py bundle dump %s %s" % (deal_slug, fixture_file))
Ejemplo n.º 5
0
    def addon(self, action='', *addons):
        """
        Executes an add/remove/upgrade action to the remote heroku addons.

        Args:
            action: string addon action. either add, remove, or upgrade
            addons: list of addons

        Usage:
            blt e:[env] heroku.addon [add|remove|upgrade] ["addon:level"]

        Examples:
            blt e:s heroku.addon - default lists the current addons on staging
            blt e:s heroku.addon add - adds *ALL* addons defined in beltenv
                configuration file
            blt e:p heroku.addon add "newrelic:standard" - adds the standard
                version of newrelic in production
            blt e:p heroku.addon remove newrelic - removes newrelic from prod
        """
        if not action:
            local('heroku addons --app %s' % self.cfg['heroku']['app'])
        else:
            if not addons:
                # much like the "config" command above, we want to convert the
                # configured addons to a list of "addon:level" pairs
                addons = [''.join([k,':',v])
                    for k,v in self.cfg['heroku']['addons'].iteritems()]

            for addon in addons:
                local('heroku addons:%s %s --app %s' % (action,
                                                        addon,
                                                        self.cfg['heroku']['app']))
Ejemplo n.º 6
0
    def domain(self, action=None, *domains):
        """
        Executes an add/clear/remove action to the remote heroku domains.

        Args:
            action: domain action. either add, clear, or remove
            domains: list of domains

        Usage:
            blt e:[env] heroku.domain [add|clear|remove] [domain]

        Examples:
            blt e:s heroku.domain - default, lists the current domains on staging
            blt e:s heroku.domain add - adds *ALL* domains defined in beltenv
                configuration file
            blt e:p heroku.domain add "matter.com" - adds the "matter.com"
                domain to the production heroku app
            blt e:p heroku.domain clear - clears all domains in production
        """
        if not action:
            local('heroku domains --app %s' % self.cfg['heroku']['app'])
        else:
            if not domains:
                domains = self.cfg['heroku']['domains']

            for domain in domains:
                local('heroku domains:%s %s --app %s' % (action,
                                                        domain,
                                                        self.cfg['heroku']['app']))
Ejemplo n.º 7
0
    def load(self, deal_slug, database):
        """
        Loads a deal from a fixture file.

        This will load the fixture located in the BUNDLE_ROOT directory to the
        passed in database target. Special care has been taken to allow this
        command to detect previously loaded data and can be run multiple times
        without affecting existing database entries. If you need to push a fresh
        update, use the ``delete`` command to start with a fresh slate.

        Args:
            deal_slug: the unique slug for the deal
            database: the database to load into

        Usage:
            blt bundle.load (deal_slug) (database)

        Examples:
            blt bundle.load blumhouse-productions PRODUCTION
        """
        environ["DATABASE_URL"] = self.cfg["bundle"][database]
        fixture_file = self._fixture_file(deal_slug)

        with cd(self.cfg["django"]["DJANGO_ROOT"]):
            local("python manage.py bundle load %s" % fixture_file)
Ejemplo n.º 8
0
    def gunicorn_server(self, *args):
        "Runs Gunicorn server for pseudo-production testing."
        project = self.cfg['django']['PROJECT_DIR']
        args_str = ''.join(args)

        with cd(self.cfg['django']['DJANGO_ROOT']):
            flag_str = '%s --access-logfile=- --error-logfile=-' % args_str
            local('gunicorn %s %s.wsgi:application' % (flag_str, project))
Ejemplo n.º 9
0
    def info(self):
        """
        Shows the info for your current heroku environment

        Usage:
            blt e:[env] heroku.info
        """
        local('heroku apps:info --app %s' % self.cfg['heroku']['app'])
Ejemplo n.º 10
0
    def test(self, *apps):
        """
        Runs py.test for the django project.

        If <apps> is empty, all tests will be run. Otherwise, tests may be specified in the
        following way: <appname>[.<search_phrase_1>[.<search_phrase_2>...<search_phrase_n>]].

        For example, given an app named "my_app" and a test defined by unittest as
        "MyTestCase.test_something" the following command would run just that test:
        "blt django.test my_app.MyTestCase.test_something". To run every test in the test case:
        "blt django.test my_app.MyTestCase". Or, to run every test for the app:
        "blt django.test my_app".

        Specifying multiple apps is also possible: "blt django.test my_app,my_other_app,your_app".
        However, due to the way test searching is performed by py.test, it is not recommended
        to use search phrases when testing multiple apps.

        Usage:
            blt django.test [apps]

        Examples:
            blt django.test - default, runs all tests in the project
            blt django.test my_app1 my_app2 - runs all tests for my_app1 and my_app2
            blt django.test my_app.test_case - runs the test_case in my_app
        """
        project = self.cfg['django']['PROJECT_DIR']

        # first clear out any .pyc files.  these are cached and could provide
        # bad test results.  example: you import a module in your test case,
        # but have deleted it on the filesystem.  if the .pyc file still
        # exists, the test will still pass.
        local('find . -name "*.pyc" -exec rm -f {} \;')

        test_names = []
        app_names = []
        flags = []
        args = []

        for n in apps:
            if n.startswith('-'):
                flags.append(n)
            elif '.' in n:
                a, t = n.split('.', 1)
                app_names.append(a)
                test_names += t.split('.')
            else:
                app_names.append(n)

        args.append(' '.join(flags))
        args.append(' '.join(app_names))
        args.append('-k "%s"' % ' and '.join(test_names) if len(test_names) else '')
        command = 'py.test --ds {0}.settings {1}'.format(project,
                                                         ' '.join(args)).strip()

        with cd(self.cfg['django']['DJANGO_ROOT']):
            local(command)
Ejemplo n.º 11
0
    def destroy(self):
        """
        Destroys a heroku app.

        The heroku toolbelt will verify this operation before executing.

        Usage:
            blt e:[env] heroku.destroy
        """
        local('heroku apps:destroy %s' % self.cfg['heroku']['app'])
Ejemplo n.º 12
0
    def covrpt(self):
        """
        This will open the html version of the coverage report in your browser.

        Usage:
            blt django.covrpt
        """
        project = self.cfg['django']['PROJECT_DIR']

        with cd(self.cfg['django']['DJANGO_ROOT']):
            local('open coverage_html/index.html')
Ejemplo n.º 13
0
Archivo: south.py Proyecto: dencold/blt
    def status(self, app=None):
        """
        Check the status of outstanding database migrations.

        Sadly, south gives us no easy api access to get status of what models
        have changed on an app. It only spits out the summary of changes to
        stderr and the actual Migration classes to stdout. The status command
        tries to encapsulate and parse this out to be helpful, but it is
        obviously brittle and should be tested whenever we upgrade the south
        library.

        Args:
            app: django app to check status for

        Usage:
            blt south.status (app)

        Examples:
            blt south.status invest - displays status for the invest app
        """
        if not app:
            msg = ("\nsouth status requires an *app* to check. for example:\n"
                    , "    blt south.status my_app\n"
                    , "To check which apps have had model changes run:\n"
                    , "    git status | grep models.py")
            abort("\n".join(msg))

        with cd(self.cfg['django']['DJANGO_ROOT']):
            puts("-- Model Check -----------------------------------------------------------")
            out = local('python manage.py schemamigration %s --auto --stdout 2>&1' % app,
                collect_output=True, abort_on_stderr=False)

            if out.strip() == 'Nothing seems to have changed.':
                puts("Model is in sync with migrations")
            else:
                puts("Model changes found:\n\n%s" % out)
                puts("\n==> Run `blt south.delta %s` to create a migration set." % app)

            puts("\n-- Unapplied Migrations --------------------------------------------------")
            out = local('python manage.py migrate %s --list | grep -v "*" 2>&1' % app,
                collect_output=True)

            if out.strip() == app:
                puts("All migrations have been applied to db")
            else:
                puts("Migrations need to be applied to db:\n%s" % out.strip())
                puts("\n==> Run `blt south.apply` to push to the database\n")
Ejemplo n.º 14
0
    def create(self):
        """
        Provisions a fully configured heroku app from scratch.

        Behind the scenes, you're getting the following:
        - heroku apps:create
        - git push heroku
        - heroku config
        - heroku addons
        - heroku domains
        - all post deploy hooks

        The command will handle creating a special git remote for the
        environment and can push from a non-master branch, things which are not
        easily accomplished with the heroku toolbelt. This is driven from the
        bltenv configuration.

        Usage:
            blt e:[env] heroku.create
        """
        print "******** Creating New Heroku App ********"
        print "App Name: " + green(self.cfg['heroku']['app'])
        print "Environment: " + green(self.cfg['blt_envtype'])
        print "Branch: " + green(self.cfg['heroku']['git_branch'])
        proceed = prompt("\nLook good? ==>", default='no')

        if proceed.lower() != 'yes' and proceed.lower() != 'y':
            abort('Aborting heroku creation.')

        local('heroku apps:create %s --remote %s' % (self.cfg['heroku']['app']
                                            , self.cfg['heroku']['git_remote']))
        self.config('set')
        self.push()
        self.addon('add')

        # if we have domains configured, add them
        if 'domains' in self.cfg['heroku']:
            self.domain('add')

        # handle post deploy steps
        self.run(*self.cfg['heroku']['post_deploy'])

        print '\nHeroku Deploy Complete!'
        url = '==> http://%s.herokuapp.com/' % self.cfg['heroku']['app']
        print url
Ejemplo n.º 15
0
    def run(self, *commands):
        """
        Runs a given command on heroku.

        Args:
            commands: list of shell commands to be run on the heroku instance

        Usage:
            blt e:[env] heroku.run "command"

        Examples:
            blt e:s heroku.run bash - opens a bash session on heroku staging
            blt e:p heroku.run "ls -altr" - runs ls -altr on heroku prod
        """

        for command in commands:
           local('heroku run "%s" --app %s' % (command
                                            , self.cfg['heroku']['app']))
Ejemplo n.º 16
0
    def cov(self, *apps):
        """
        Runs coverage for the django project.

        Note that this command will run the py.test suite first as it is required
        for generating the coverage report. If you'd like to filter to a specific
        set of apps, you can pass it into this command.

        Usage:
            blt django.cov [apps] [flags]

        Examples:
            blt django.cov - default, runs coverage for the entire project
            blt django.cov my_app1 my_app2 - runs coverage for my_app1 and my_app2
        """
        project = self.cfg['django']['PROJECT_DIR']

        # first clear out any .pyc files.  these are cached and could provide
        # bad test results.  example: you import a module in your test case,
        # but have deleted it on the filesystem.  if the .pyc file still
        # exists, the test will still pass.
        local('find . -name "*.pyc" -exec rm -f {} \;')

        app_names = []
        flags = []
        pytest_args = []
        cov_args = []

        for n in apps:
            if n.startswith('-'):
                flags.append(n)
            else:
                app_names.append(n)

        # setup py.test args
        pytest_args = ' '.join(app_names)
        cov_args = ','.join(app_names)

        if app_names:
            cmd = 'coverage run --source {0} {1} -m py.test --ds {2}.settings {3}'.format(
                cov_args,
                ' '.join(flags),
                project,
                pytest_args).strip()
        else:
            cmd = 'coverage run {0} -m py.test --ds {1}.settings'.format(
                ' '.join(flags),
                project).strip()


        with cd(self.cfg['django']['DJANGO_ROOT']):
            local(cmd)
            local('coverage report')
            local('coverage html -d coverage_html')
Ejemplo n.º 17
0
    def runserver(self, ip='127.0.0.1', port='8000'):
        """
        Runs django's development http server

        Args:
            ip: the ip address to host on, default is 127.0.0.1
            port: the port on host server, default is 8000

        Usage:
            blt django.runserver [ip] [port]

        Examples:
            blt django.runserver - default, runs on 127.0.0.1:8000
            blt django.runserver 10.1.156.3 - runs on 10.1.156.3:8000
            blt django.runserver 10.1.156.3 8888 - runs on 10.1.156.3:8888
        """
        with cd(self.cfg['django']['DJANGO_ROOT']):
            print "Setting ASSETS_DEBUG=True"
            environ['ASSETS_DEBUG'] = "True"
            local('python manage.py runserver %s:%s' % (ip, port))
Ejemplo n.º 18
0
Archivo: south.py Proyecto: dencold/blt
    def delta(self, *apps):
        """
        Creates a new schema changeset for an app.

        Unfortunately, south doesn't allow project-wide schemamigrations, you
        have to provide a specific app name.

        Args:
            apps: a list of apps to create changesets for

        Usage:
            blt south.delta (apps)

        Examples:
            blt south.delta invest payment - creates deltas for invest and
                payment apps
        """
        if not apps:
            abort('\n\nPlease provide an app name, e.g. \n    blt south.delta my_app')

        with cd(self.cfg['django']['DJANGO_ROOT']):
            for app in apps:
                local('python manage.py schemamigration %s --auto' % app)
Ejemplo n.º 19
0
    def delete(self, deal_slug, database):
        """
        Deletes a deal on the platform.

        This will completely delete the deal and all related objects on the
        passed in database. Because we view bundles as atomic units and never
        overwrite any existing entries on the database, you are required to
        run this command if you want update anything in the db.

        Args:
            deal_slug: the unique slug for the deal
            database: the database to delete from

        Usage:
            blt bundle.delete (deal_slug) (database)

        Examples:
            blt bundle.delete blumhouse-productions STAGING
        """
        environ["DATABASE_URL"] = self.cfg["bundle"][database]

        with cd(self.cfg["django"]["DJANGO_ROOT"]):
            local("python manage.py bundle delete %s" % (deal_slug))
Ejemplo n.º 20
0
    def up(self):
        """
        Update a django environment with latest settings.

        This command does everything required to get a django project running.
        These are the steps that will be executed when the command is issued:

        1. pip install requirements
        2. syncdb
        3. migrate
        4. loaddata initial
        5. collectstatic
        6. assets build

        It has been designed with rerunning in mind and can be safely executed
        without any unwelcome side affects. For example, any pip packages that
        have already been installed will be skipped on rerun. Any database
        tables will be preserved (no dropping data), etc.

        Note that this must be run in a virtualenv. blt will detect if you are
        not using one and will barf with a helpful error.

        Usage:
            blt django.up
        """
        django_root = self.cfg['django']['DJANGO_ROOT']

        # install packages from pip's requirements.txt
        local('pip install -r requirements.txt')

        with cd(django_root):
            try:
                local('python manage.py syncdb')
                local('python manage.py migrate')
            except:
                msg = '\n'.join(["ERROR: Python couldn't find django.  Are you in a virtualenv?"
                                , "Try workon MY_SWEET_VIRTENV_HERE"])
                abort(msg)

        with cd(django_root):
            # Load dev data
            local('python manage.py loaddata initial')

            # collect static files
            local('python manage.py collectstatic --noinput')

            # Compile static asset bundles
            local('python manage.py assets build')
Ejemplo n.º 21
0
 def shell(self):
     """Opens a session to django's shell"""
     with cd(self.cfg['django']['DJANGO_ROOT']):
         local('python manage.py shell')
Ejemplo n.º 22
0
 def collectstatic(self):
     """Runs django's collectstatic and the webassets build in one command"""
     with cd(self.cfg['django']['DJANGO_ROOT']):
         local('python manage.py collectstatic --noinput')
         local('python manage.py assets build')