Append the contents of latest Stackage nightly build to the global cabal config file I've made the following python script to to append the contents of the latest Stackage nightly build to the global cabal config file (instead of going to the site, copying the page and appending it manually...). I would appreciate your feedback:

"""
Appends the latest stackage nightly sources from Stackage(http://www.stackage.org/nightly)
to your global cabal config file

It also makes two backups: one of the appended file and one of the unappended file

Stackage(http://www.stackage.org/) is a stable source of Haskell packages
"""

import requests
import shutil
from os.path import expanduser
from os.path import join

cabal_config_path = expanduser('~/.cabal/config')
stackage_nightly_url = 'https://www.stackage.org/nightly/cabal.config?global=true'

def write_cabal_config_backup(filename):
    """ 
    Writes a backup of the current global cabal config file in the ~/.cabal directory
    """
    shutil.copyfile(cabal_config_path, 
        join(expanduser('~/.cabal'), filename))

def unappend_stackage():
    """
    Unappend stackage sources from the global cabal config file. Be careful that 
    the sources must be at the end of the file, or this function will delete things 
    that you don't want it to.
    """
    def unappended_cabal_config():
        # Searches for the string 'Stackage' and returns a list made of the lines
        # of the file from there up, excluding the 'Stackage' line and everything below.
        with open(cabal_config_path) as f:
            cabal_config = f.readlines()
            for i in range(len(cabal_config)):
                if 'Stackage' in cabal_config[i]:
                    return cabal_config[:i]
        return cabal_config
    def write_unappended_cabal_config():
        cabal_config = unappended_cabal_config()
        with open(cabal_config_path, 'wt') as f:
            for line in cabal_config:
                f.write(line)
    write_unappended_cabal_config()

def append_stackage_nightly():
    """
    Appends stackage nightly sources to the global cabal config file
    """
    def get_stackage_nightly():
        r = requests.get(stackage_nightly_url)
        if r.status_code == 200:
            return r.text
    stackage_nightly = get_stackage_nightly()
    if stackage_nightly:
        with open(cabal_config_path, 'a') as f:
            f.write(stackage_nightly)

if __name__ == '__main__':
    write_cabal_config_backup('config_backup_appended')
    unappend_stackage()
    write_cabal_config_backup('config_backup_unappended')
    append_stackage_nightly()
The unappend_cabal_config can be more efficient and more elegant using a generator:


Reading all the lines from the file when you may only need the ones until one containing "Stackage" is wasteful
It's good to avoid the index variable in loops when possible


Like this:

def unappend_cabal_config():
    with open(cabal_config_path) as fh:
        for line in fh:
            if 'Stackage' in line:
                return
            yield line