r"""
     _
    (_)   _      __
    | | /'_`\  /'__`\
    | |( (_) )(  ___/
 _  | |`\___/'`\____)
( )_| |
`\___/'


joe generates .gitignore files from the command line for you

Usage:
  joe (ls | list)
  joe [NAME...]
  joe (-h | --help)
  joe --version

Options:
  -h --help     Show this screen.
  --version     Show version.

"""


import os

from docopt import docopt


__version__ = '0.0.6'


_ROOT = os.path.abspath(os.path.dirname(__file__))


def _get_data_dir(path):
    '''Returns the path to the directory matching the passed `path`.'''
    return os.path.dirname(os.path.join(_ROOT, 'data', path))


def _walk_gitignores():
    '''Recurse over the data directory and return all .gitignore file names'''
    gitignores = []
    for _root, _sub_folders, files in os.walk(DATA_DIR):
        gitignores += [f.replace('.gitignore', '')
                       for f in files if f.endswith('.gitignore')]
    return sorted(gitignores)


# Where all gitignore files are
DATA_DIR = _get_data_dir('*.gitignore')
# Load up names for all gitignore files
GITIGNORE_RAW = _walk_gitignores()
GITIGNORE = [filename.lower() for filename in GITIGNORE_RAW]


def _print_filenames():
    '''List all available .gitignore files.'''
    print ', '.join(GITIGNORE)


def _handle_gitignores(names):
    '''Generates and sends the gitignore contents to stdout.'''
    output = '#### joe made this: https://goel.io/joe\n'
    for name in names:
        try:
            raw_name = GITIGNORE_RAW[GITIGNORE.index(name.lower())]
        except ValueError:
            print ('Uh oh! Seems like joe doesn\'t know what %s is.\n'
                   'Try running `joe ls` to see list of available gitignore '
                   'files.') % name
            break
        output += _fetch_gitignore(raw_name)
    print output


def _fetch_gitignore(raw_name, directory=''):
    '''Returns a the corresponding .gitignore as a string.

    It is assumed that raw_name is a valid .gitignore filename.
    Given a raw_name, it will look in data/ and then data/Global/ for a
        matching .gitignore.
    An empty string as a default argument evaluates to None.
    directory must then be checked as string operations such as
        string + None return ''
    '''
    output = '\n#####=== %s ===#####\n' % raw_name
    if directory:
        filepath = os.path.join(DATA_DIR, '%s/%s.gitignore' %
                                (directory, raw_name))
    else:
        filepath = os.path.join(DATA_DIR, raw_name + '.gitignore')
        output += '\n'
    try:
        with open(filepath) as gitignore:
            output += gitignore.read()
        return output
    except IOError:
        return _fetch_gitignore(raw_name, 'Global')


def main():
    '''joe generates .gitignore files from the command line for you'''
    arguments = docopt(__doc__, version=__version__)

    if arguments['ls'] or arguments['list']:
        _print_filenames()
    elif arguments['NAME']:
        _handle_gitignores(arguments['NAME'])
    else:
        print __doc__


if __name__ == '__main__':
    main()

@@ -338,16 +338,27 @@
 mport os
+%0Aimport sys
 %0A%0Afrom d
@@ -1162,20 +1162,18 @@
 %0A%0A%0Adef _
-prin
+ge
 t_filena
@@ -1230,21 +1230,22 @@
 '''%0A    
-print
+return
  ', '.jo
@@ -1316,12 +1316,14 @@
 and 
-send
+return
 s th
@@ -1346,18 +1346,8 @@
 ents
- to stdout
 .'''
@@ -1400,24 +1400,40 @@
 l.io/joe%5Cn'%0A
+    failed = %5B%5D%0A
     for name
@@ -1536,105 +1536,229 @@
     
-except ValueError:%0A            print ('Uh oh! Seems like joe doesn%5C't know what %25s is.%5Cn'%0A       
+    output += _fetch_gitignore(raw_name)%0A        except ValueError:%0A            failed.append(name)%0A    if failed:%0A        sys.stderr.write((%0A            'joe doesn%5C't know the following gitignores:'%0A            '%5Cn%25s%5Cn'%0A
     
@@ -1821,17 +1821,20 @@
 itignore
- 
+s.%5Cn
 '%0A      
@@ -1839,108 +1839,41 @@
     
-           'files.') %25 name%0A            break%0A        output += _fetch_gitignore(raw_name)%0A    print
+) %25 %22%5Cn%22.join(failed))%0A    return
  out
@@ -2980,14 +2980,18 @@
     
-_
 print
+(_get
 _fil
@@ -2998,16 +2998,17 @@
 enames()
+)
 %0A    eli
@@ -3036,16 +3036,22 @@
         
+print(
 _handle_
@@ -3079,16 +3079,17 @@
 'NAME'%5D)
+)
 %0A    els
@@ -3108,16 +3108,17 @@
 rint
- 
+(
 __doc__
+)
 %0A%0A%0Ai

Use stderr, python3 support