cookiecutter: Don’t strip trailing newlines from files

I’m using cookiecutter to generate new project templates for our new, PSR-2 compliant PHP projects at work. Unfortunately PSR2 mandates that each file has a trailing new line at the end, but cookiecutter strips them off.

I found the following pull request which adds the functionality that I need (don’t remove trailing new lines), but it hasn’t been merged yet. Thankfully, someone posted a post-gen hook that I can use until then. The hook iterates over every file and adds a new line character back in if it needs to. It was almost there, but had a few bugs for me.

The provided one didn’t work when files were empty (it threw an IOError) and the shebang line didn’t work (it threw an OSError). Once I’d fixed those two issues up, it worked perfectly.

Here’s my fixed up version:

#!/usr/bin/env python
import os

from binaryornot.check import is_binary

def main():
    root_path = os.getcwd()
    for dirpath, dirnames, filenames in os.walk(root_path):
        for filename in filenames:
            path = os.path.join(dirpath, filename)
            if not is_binary(path):
                fd = open(path, 'a+b')
                try:
                    fd.seek(-1, os.SEEK_END)
                    if not fd.read(1) == '\n':
                        fd.seek(0, os.SEEK_END)
                        fd.write('\n')
                except IOError:
                    # This was an empty file, so do nothing
                    pass

if __name__ == '__main__':
    main()

Michael is a polyglot software engineer, committed to reducing complexity in systems and making them more predictable. Working with a variety of languages and tools, he shares his technical expertise to audiences all around the world at user groups and conferences. You can follow @mheap on Twitter

Thoughts on this post

Axel F 2014-09-29

Tried your solution, but I needed to run shell command in the post gen hook, and running the script by a python command in not very flexible. So I used sed one liner instead.
here is a simple post_gen_project.sh:

find . -type f | xargs sed -i -e ‘$a\’
git init
git flow init -d

Makes my life easier

Leave a comment?

Leave a Reply