v{VERSION}
    This script makes a command line script out of a python script.
    For example, 'clingon script.py' will copy or symlink script.py
    (without the .py extension) to:
    - <python-exe-path>/script (default),
    - <target-path>/script if --target-path is specfied,
    - ~/bin/script if --user is specified,
    and then set the copy / symlink as executable.
    See https://github.com/francois-vincent/clingon

def make_script(python_script, target_path='', target_name='', user=False, make_link=False,
                force=False, remove=False, no_check_shebang=False, no_check_path=False):
    """v{VERSION}
    This script makes a command line script out of a python script.
    For example, 'clingon script.py' will copy or symlink script.py
    (without the .py extension) to:
    - <python-exe-path>/script (default),
    - <target-path>/script if --target-path is specfied,
    - ~/bin/script if --user is specified,
    and then set the copy / symlink as executable.
    See https://github.com/francois-vincent/clingon
    """
    if user and target_path:
        raise RunnerErrorWithUsage("You cannot specify --path and --user at the same time")
    source = os.path.abspath(python_script)
    dest_dir = os.path.normpath(os.path.expanduser('~/bin' if user else target_path or os.path.dirname(sys.executable)))
    target = os.path.join(dest_dir, target_name if target_name else os.path.splitext(os.path.basename(source))[0])
    target_exists = os.path.exists(target)
    if remove:
        if target_exists:
            os.unlink(target)
            print("Script '%s' removed" % target)
        else:
            print("Script '%s' not found, nothing to do" % target)
        return
    if not os.path.exists(source):
        raise RunnerError("Could not find source '%s', aborting" % source)
    if DEBUG:
        print('Source, target:', source, target)

    if target_exists:
        def same_file_same_type(source, target):
            if os.path.islink(target):
                return make_link and os.path.samefile(source, target)
            else:
                return not make_link and (open(source, 'rb').read() == open(target, 'rb').read())

        if same_file_same_type(source, target):
            print("Target '%s' already created, nothing to do" % target)
            return
        elif not force:
            raise RunnerError("Target '%s' already exists, aborting" % target)

    if not os.path.isdir(dest_dir):
        # Create directory
        try:
            os.makedirs(dest_dir)
        except OSError:
            raise RunnerError("Target folder '%s' does not exist, and cannot create it, aborting" % dest_dir)

    if not no_check_shebang:
        # Check that file starts with python shebang (#!/usr/bin/env python)
        first_line = open(source).readline()
        if not ('#!' in first_line and 'python' in first_line):
            raise RunnerError("Your script's first line should start with '#!' and contain 'python', aborting")

    # Now it's time to copy or symlink file
    if target_exists:
        os.unlink(target)
    import stat

    perms = stat.S_IXUSR | stat.S_IXGRP
    if os.getuid() == 0:
        perms |= stat.S_IXOTH
    if make_link:
        st = os.stat(source)
        if st.st_mode & perms != perms:
            os.chmod(source, st.st_mode | perms)
        os.symlink(source, target)
        st = os.stat(target)
        os.chmod(target, st.st_mode | perms)
        print('Script %s has been symlinked to %s' % (source, target))
    else:
        import shutil

        shutil.copyfile(source, target)
        st = os.stat(target)
        os.chmod(target, st.st_mode | perms)
        print('Script %s has been copied to %s' % (source, target))
        # check PATH and advise user to update it if relevant
    path_env = os.environ.get('PATH')
    if not no_check_path and (not path_env or dest_dir not in path_env):
        print("Please add your local bin path [%s] to your environment PATH" % dest_dir)