A glorious command line tool to make your life with git, GitHub
    and Bugzilla much easier.
763362
def cli(config, configfile, verbose):
    """"""
    config.verbose = verbose
    config.configfile = configfile
    if not os.path.isfile(configfile):
        state.write(configfile, {})
710966
def _update_github(
            self):
        
        self.log.debug('starting the ``_update_github`` method')

        from subprocess import Popen, PIPE, STDOUT
        gdir = self.settings["sherlock wiki root"]
        cmd = """cd %(gdir)s && git add --all && git commit -m "x" && git pull origin master && git push origin master""" % locals()
        p = Popen(cmd, stdout=PIPE, stdin=PIPE, shell=True)
        output = p.communicate()[0]
        print output
        self.log.debug('output: %(output)s' % locals())

        self.log.debug('completed the ``_update_github`` method')
        return None
847637
function cli(args) {
    const { _: [command] } = args;
    return getModule(command).default(args)
        .catch(err => {
            getModule('input').emitError(err.message);
            process.exit(1);
        });
}
125545
function GitHub(ready, user, pass, useSsh) {

  var opts = {
    version: '3.0.0',
    timeout: 30000
  };

  var proxy = bag.proxy();
  if (proxy) {
    proxy = url.parse(proxy);
    opts.proxy = {
      host: proxy.hostname,
      port: proxy.port
    };
  }

  this.gh = new github(opts);
  this.useSsh = useSsh;

  var self = this;
  if (user && pass) {
    // if credentials are provided, use those to authenticate
    self.gh.authenticate({
      type: 'basic',
      username: user,
      password: pass
    });
    // the other branches (oauth and no authentication only call the ready()
    // callback after another callback has resolved, which guarantees that this
    // (constructor) function has returned before the ready callback has been
    // called. This, in turn, ensures that the code calling this constructor has received a constructed object. To ensure this also for the basic auth case, we need to make this asynchronous as well.
    process.nextTick(ready);
  } else {
    var gitHubAuth = new GithubAuth();
    gitHubAuth
      .readAuthToken()
      .then(function success(token) {
        self.gh.authenticate({
          type : 'oauth',
          token : token
        });
        ready();
      }, function error() {
        // no auth token, user did not execute repoman --signin
        // continue without authentication
        ready();
    });
  }
}
851395
def main():
    
    parser = argparse.ArgumentParser(
        description='Performs option handling operations from the command-line. Calls JVM start/stop automatically.')
    parser.add_argument("-j", metavar="classpath", dest="classpath", help="additional classpath, jars/directories")
    parser.add_argument("-action", metavar="action", dest="action", required=True,
                        help="The action to perform on the options: join=create single string, "\
                             "split=create array from quoted option, code=generate code from options")
    parser.add_argument("option", nargs=argparse.REMAINDER, help="The option(s) to process")
    parsed = parser.parse_args()
    jars = []
    if parsed.classpath is not None:
        jars = parsed.classpath.split(os.pathsep)

    jvm.start(jars, packages=True)

    try:
        if parsed.action == "join":
            output = "cmdline = \"" + backquote(join_options(parsed.option)) + "\""
        elif parsed.action == "split" and len(parsed.option) == 1:
            output = "options = [\n"
            opts = split_options(parsed.option[0])
            for idx, opt in enumerate(opts):
                if idx > 0:
                    output += ",\n"
                output += "    \"" + backquote(opt) + "\""
            output += "]"
        elif parsed.action == "code":
            options = parsed.option[:]
            cname = None
            # classname + options?
            if options[0].find(".") > -1:
                cname = options[0]
                options = options[1:]
            output = "options = [ \n"
            for idx, opt in enumerate(options):
                if idx > 0:
                    output += ",\n"
                output += "    \"" + backquote(opt) + "\""
            output += "]\n"
            if cname is not None:
                output += 'handler = OptionHandler(JavaObject.new_instance("' + cname + '"))\n'
                output += 'handler.options = options\n'
        else:
            raise Exception("Unsupported action: " + parsed.action)
        if output is not None:
            print(output)
    except Exception as e:
        print(e)
    finally:
        jvm.stop()
971415
def main_cli(ctx, verbose=False):
    
    sTime = time.time()
    if ctx.obj is None:  # Fix for bug (as of 3.0)
        # https://github.com/pallets/click/issues/888
        ctx.obj = {}
    ctx.obj['VERBOSE'] = verbose
    ctx.obj['STIME'] = sTime

    click.secho("Ontospy " + VERSION, fg='white')
    # click.secho("------------", fg='white')
    if not verbose and ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())
964468
function executeGit( args, options ) {
	options = options || {};
	return new Promise( function( resolve, reject ) {
		var stdo = '';
		var proc = doSpawn( 'git', args, { cwd: options.cwd ? options.cwd : process.cwd(), stdio: [ 'ignore', 'pipe', 'ignore' ] } );

		function unpipe() {
		}

		if ( options.captureStdout ) {
			proc.stdout.on( 'data', function onStdout( data ) {
                       		stdo += data.toString();
                	} );
		}
		proc.on( 'error', function( err ) {
			unpipe();
			if ( options.ignoreError ) {
				resolve( { out: stdo, code: 0 } );
			} else {
				printError( err, args );
				reject( err );
			}
		} );
		proc.on( 'exit', function( code ) {
			unpipe();
		} );
		proc.on( 'close', function( code ) {
			unpipe();
			if ( code !== 0 && !options.ignoreError ) {
				if ( !options.quiet ) {
					printError( '', args );
				}
				reject( new Error( "Error running git" ) );
			} else {
				resolve( { out: stdo, code: code } );
			}
		} );
	} );
}
756499
def main(arguments=None):
    
    # setup the command-line util settings
    su = tools(
        arguments=arguments,
        docString=__doc__,
        logLevel="ERROR",
        options_first=True
    )
    arguments, settings, log, dbConn = su.setup()

    # tab completion for raw_input
    readline.set_completer_delims(' \t\n;')
    readline.parse_and_bind("tab: complete")
    readline.set_completer(tab_complete)

    # unpack remaining cl arguments using `exec` to setup the variable names
    # automatically
    for arg, val in arguments.iteritems():
        if arg[0] == "-":
            varname = arg.replace("-", "") + "Flag"
        else:
            varname = arg.replace("<", "").replace(">", "")
        if isinstance(val, str) or isinstance(val, unicode):
            exec(varname + " = '%s'" % (val,))
        else:
            exec(varname + " = %s" % (val,))
        if arg == "--dbConn":
            dbConn = val
        log.debug('%s = %s' % (varname, val,))

    ## START LOGGING ##
    startTime = times.get_now_sql_datetime()
    log.info(
        '--- STARTING TO RUN THE cl_utils.py AT %s' %
        (startTime,))

    # set options interactively if user requests
    if "interactiveFlag" in locals() and interactiveFlag:

        # load previous settings
        moduleDirectory = os.path.dirname(__file__) + "/resources"
        pathToPickleFile = "%(moduleDirectory)s/previousSettings.p" % locals()
        try:
            with open(pathToPickleFile):
                pass
            previousSettingsExist = True
        except:
            previousSettingsExist = False
        previousSettings = {}
        if previousSettingsExist:
            previousSettings = pickle.load(open(pathToPickleFile, "rb"))

        # x-raw-input
        # x-boolean-raw-input
        # x-raw-input-with-default-value-from-previous-settings

        # save the most recently used requests
        pickleMeObjects = []
        pickleMe = {}
        theseLocals = locals()
        for k in pickleMeObjects:
            pickleMe[k] = theseLocals[k]
        pickle.dump(pickleMe, open(pathToPickleFile, "wb"))

    # call the worker function
    # x-if-settings-or-database-credientials
    if cone and filelist:
        import codecs
        pathToReadFile = pathToCoordinateList
        readFile = codecs.open(pathToReadFile, encoding='utf-8', mode='r')

        listOfCoordinates = []
        for line in readFile.readlines():
            line = line.strip()
            [ra, dec] = line.split()
            listOfCoordinates.append(str(ra) + " " + str(dec))
        search = conesearch(
            log=log,
            radiusArcsec=radiusArcsec,
            nearestOnly=nearestFlag,
            unclassified=unclassifiedFlag,
            listOfCoordinates=listOfCoordinates,
            outputFilePath=outPutFile,
            verbose=verboseFlag,
            redshift=redshiftFlag)
    elif cone:
        search = conesearch(
            log=log,
            ra=ra,
            dec=dec,
            radiusArcsec=radiusArcsec,
            nearestOnly=nearestFlag,
            unclassified=unclassifiedFlag,
            outputFilePath=outPutFile,
            verbose=verboseFlag,
            redshift=redshiftFlag
        )
    elif obj:
        search = namesearch(
            log=log,
            names=objectName,
            verbose=verboseFlag,
            outputFilePath=outPutFile
        )
    search.get()

    if "dbConn" in locals() and dbConn:
        dbConn.commit()
        dbConn.close()
    ## FINISH LOGGING ##
    endTime = times.get_now_sql_datetime()
    runningTime = times.calculate_time_difference(startTime, endTime)
    log.info('-- FINISHED ATTEMPT TO RUN THE cl_utils.py AT %s (RUNTIME: %s) --' %
             (endTime, runningTime, ))

    return
840650
def github(cls, user, repo):
    
    # For the url format, see: http://maven.apache.org/scm/git.html
    params = dict(user=user, repo=repo)
    connection = 'scm:git:git@github.com:{user}/{repo}.git'.format(**params)
    url = 'https://github.com/{user}/{repo}'.format(**params)
    return cls(connection=connection, developer_connection=connection, url=url)
1010300
def cli():
    
    with open_client(cache_dir=get_cache_dir()) as client:
        tip = client.frog_tip()

    terminal_width = click.termui.get_terminal_size()[0]
    wisdom = make_frog_fresco(tip, width=terminal_width)

    click.echo(wisdom)
73890
def cmd(send, msg, args):
    
    repo = args['config']['api']['githubrepo']
    apikey = args['config']['api']['githubapikey']
    if not repo:
        send("GitHub repository undefined in config.cfg!")
        return
    parser = arguments.ArgParser(args['config'])
    parser.add_argument('title', nargs='*', default='')
    parser.add_argument('--get', '--show', action='store_true')
    parser.add_argument('--description', nargs='+', default="No description given.")
    cmdargs, remainder = parser.parse_known_args(msg)
    if isinstance(cmdargs.title, list):
        cmdargs.title = ' '.join(cmdargs.title)
    if isinstance(cmdargs.description, list):
        cmdargs.description = ' '.join(cmdargs.description)
    if remainder:
        cmdargs.title = "%s %s" % (cmdargs.title, ' '.join(remainder))
    if args['type'] == 'privmsg':
        send('You want to let everybody know about your problems, right?')
    elif cmdargs.get or cmdargs.title.isdigit():
        issue = get('https://api.github.com/repos/%s/issues/%d' % (repo, int(cmdargs.title))).json()
        if 'message' in issue:
            send("Invalid Issue Number")
        else:
            send("%s (%s) -- %s" % (issue['title'], issue['state'], issue['html_url']))
    elif not cmdargs.title:
        issues = []
        n = 1
        while True:
            headers = {'Authorization': 'token %s' % apikey}
            page = get('https://api.github.com/repos/%s/issues' % repo, params={'per_page': '100', 'page': n}, headers=headers).json()
            n += 1
            if page:
                issues += page
            else:
                break
        if len(issues) == 0:
            send("No open issues to choose from!")
        else:
            issue = choice(issues)
            num_issues = len([x for x in issues if 'pull_request' not in x])
            send("There are %d open issues, here's one." % num_issues)
            send("#%d -- %s -- %s" % (issue['number'], issue['title'], issue['html_url']))
    elif cmdargs.title and args['is_admin'](args['nick']):
        url, success = create_issue(cmdargs.title, cmdargs.description, args['source'], repo, apikey)
        if success:
            send("Issue created -- %s -- %s -- %s" % (url, cmdargs.title, cmdargs.description))
        else:
            send("Error creating issue: %s" % url)
    elif cmdargs.title:
        row = Issues(title=cmdargs.title, description=cmdargs.description, source=str(args['source']))  # str needed to make mysqlconnector happy
        args['db'].add(row)
        args['db'].flush()
        send("New Issue: #%d -- %s -- %s, Submitted by %s" % (row.id, cmdargs.title, cmdargs.description, args['nick']),
             target=args['config']['core']['ctrlchan'])
        send("Issue submitted for approval.", target=args['nick'])
    else:
        send("Invalid arguments.")
1260977
def run_git_concurrently(base_dir):
    """"""
    os.chdir(base_dir)
    git_dirs = get_list_of_git_directories()
    print("Processing %d git repos: %s" % (len(git_dirs), ', '.join(git_dirs)))

    widgets = [Percentage(),
               ' ', Bar(),
               ' ', Counter(),
               ' ', AdaptiveETA()]

    pbar = ProgressBar(widgets=widgets, maxval=len(git_dirs))
    pbar.start()

    threads = {git_dir:GitPuller(git_dir) for git_dir in git_dirs}
    for thread in threads.values():
        thread.start()

    while True:
        pbar.update(len([t for t in threads.values() if not t.is_alive()]))
        if all([not t.is_alive() for t in threads.values()]):
            break
        time.sleep(0.2)

    table = PrettyTable(["repo", "local", "pull"])
    table.align["repo"] = "l"
    table.align["local"] = "l"
    table.align["pull"] = "l"

    for git_dir in sorted(threads):
        thread = threads[git_dir]
        if thread.local_ok:
            if thread.has_uncommitted_changes:
                local_changes_text = colored(
                    'Uncommitted changes', 'green', attrs=['bold'])
            else:
                local_changes_text = colored('OK', 'green')
        else:
            local_changes_text = colored('Problem', 'red')

        if thread.git_pull_ok:
            if thread.is_up_to_date:
                pull_text = colored('OK', 'green')
            else:
                pull_text = colored('Changed', 'green', attrs=['bold'])
        else:
            pull_text = colored('Problem', 'red')

        table.add_row([git_dir, local_changes_text, pull_text])

    print(table)
    for git_dir in sorted(threads):
        if not threads[git_dir].git_pull_ok:
            thread = threads[git_dir]
            print colored('%s: ' % git_dir, 'red')
            print thread.git_pull_output
297592
def main(arguments=None):
    
    # setup the command-line util settings

    dev_flag = False

    su = tools(
        arguments=arguments,
        docString=__doc__,
        logLevel="DEBUG",
        options_first=False,
        projectName="rockAtlas"
    )
    arguments, settings, log, dbConn = su.setup()

    # unpack remaining cl arguments using `exec` to setup the variable names
    # automatically
    for arg, val in arguments.iteritems():
        if arg[0] == "-":
            varname = arg.replace("-", "") + "Flag"
        else:
            varname = arg.replace("<", "").replace(">", "")
        if varname == "import":
            varname = "iimport"
        if isinstance(val, str) or isinstance(val, unicode):
            exec(varname + " = '%s'" % (val,))
        else:
            exec(varname + " = %s" % (val,))
        if arg == "--dbConn":
            dbConn = val
        log.debug('%s = %s' % (varname, val,))

    ## START LOGGING ##
    startTime = times.get_now_sql_datetime()
    log.info(
        '--- STARTING TO RUN THE cl_utils.py AT %s' %
        (startTime,))

    if init:
        from os.path import expanduser
        home = expanduser("~")
        filepath = home + "/.config/rockAtlas/rockAtlas.yaml"
        try:
            cmd = """open %(filepath)s""" % locals()
            p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
        except:
            pass
        try:
            cmd = """start %(filepath)s""" % locals()
            p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
        except:
            pass

    # CALL FUNCTIONS/OBJECTS
    if bookkeeping:
        from rockAtlas.bookkeeping import bookkeeper
        bk = bookkeeper(
            log=log,
            settings=settings,
            fullUpdate=fullFlag
        )
        bk.clean_all()

    if astorb:
        from rockAtlas.orbital_elements import astorb
        oe = astorb(
            log=log,
            settings=settings
        )
        oe.refresh()

    if pyephem:

        from rockAtlas.positions import pyephemPositions
        pyeph = pyephemPositions(
            log=log,
            settings=settings,
            dev_flag=dev_flag
        )
        pyeph.get(singleSnapshot=oneFlag)

    if orbfit:
        from rockAtlas.positions import orbfitPositions
        oe = orbfitPositions(
            log=log,
            settings=settings,
            dev_flag=dev_flag
        )
        oe.get(singleExposure=oneFlag)

    if cache:
        from rockAtlas.phot import download
        data = download(
            log=log,
            settings=settings,
            dev_flag=dev_flag
        )
        data.get(days=days)

    if dophot:
        from rockAtlas.phot import dophotMatch
        dp = dophotMatch(
            log=log,
            settings=settings
        )
        dp.get()

    if cycle:
        from rockAtlas.phot import download
        from rockAtlas.positions import pyephemPositions
        from rockAtlas.positions import orbfitPositions
        from rockAtlas.phot import dophotMatch
        from fundamentals.mysql import readquery

        # INITIAL ACTIONS
        # SETUP ALL DATABASE CONNECTIONS
        from rockAtlas import database
        db = database(
            log=log,
            settings=settings
        )
        dbConns, dbVersions = db.connect()
        atlas3DbConn = dbConns["atlas3"]
        atlas4DbConn = dbConns["atlas4"]
        atlasMoversDBConn = dbConns["atlasMovers"]

        while True:

            if dev_flag:
                o = " and dev_flag = 1"
            else:
                o = " "

            sqlQuery = u"""
                select distinct floor(mjd) from (
select mjd from atlas_exposures where dophot_match = 0 %(o)s
union all
select mjd from day_tracker where processed = 0 %(o)s) as a;
            """ % locals()
            rows = readquery(
                log=log,
                sqlQuery=sqlQuery,
                dbConn=atlasMoversDBConn,
                quiet=False
            )

            if len(rows) == 0:
                if dev_flag:
                    print "Processing of the ATLAS development dataset is now complete and up to date"
                else:
                    print "Processing of ATLAS data is now complete and up to date"
                break

            start_time = time.time()

            data = download(
                log=log,
                settings=settings,
                dev_flag=dev_flag
            )
            data.get(days=days)

            print "%d seconds to download ATLAS cache of %s days\n" % (time.time() - start_time, days)
            start_time = time.time()

            pyeph = pyephemPositions(
                log=log,
                settings=settings,
                dev_flag=dev_flag
            )
            pyeph.get()

            print "%d seconds to generate pyephem snapshots\n" % (time.time() - start_time,)
            start_time = time.time()

            oe = orbfitPositions(
                log=log,
                settings=settings,
                dev_flag=dev_flag
            )
            oe.get()

            print "%d seconds to generate orbfit positions\n" % (time.time() - start_time,)
            start_time = time.time()

            dp = dophotMatch(
                log=log,
                settings=settings
            )
            dp.get()

            print "%d seconds to extract dophot measurements\n" % (time.time() - start_time,)
            start_time = time.time()

    if "dbConn" in locals() and dbConn:
        dbConn.commit()
        dbConn.close()
    ## FINISH LOGGING ##
    endTime = times.get_now_sql_datetime()
    runningTime = times.calculate_time_difference(startTime, endTime)
    log.info('-- FINISHED ATTEMPT TO RUN THE cl_utils.py AT %s (RUNTIME: %s) --' %
             (endTime, runningTime, ))

    return
323659
function(conf, choices) {

    // Start by ensuring our SSH keys are good to go
    return commands.ensureKeys()

    // Then pull a screenshot
    .then(function() {
      return pullScreenshot(conf.uuid, conf.env);
    })

    // Ensure our git perms are excellent
    .then(function() {
      return commands.ensureGitPerms();
    })

    // Then grab our Pantheon aliases
    .then(function() {
      return terminus.getSiteAliases();
    })

    // Then pull our code
    .then(function() {
      return pullCode(conf.site, conf.env);
    })

    // Then ensure our symlink
    .then(function() {
      return commands.ensureSymlink();
    })

    // Then pull our DB if selected
    .then(function() {
      if (choices.database && choices.database !== 'none') {
        return pullDB(conf.site, choices.database, choices.newbackup);
      }
    })

    // THen pull our files if selected
    .then(function() {
      if (choices.files && choices.files !== 'none') {
        var newBackup = choices.newbackup;
        return pullFiles(conf.site, conf.uuid, choices.files, newBackup);
      }
    })

    // Then rebuild caches and registries as appropriate
    .then(function() {
      return rebuild();
    });

  }
1012981
function gitTag () {
      // If the tag exists, skip tagging
      if (shelljs.exec('git ls-remote --tags --exit-code ' + remoteName + ' ' + options.tag, {silent: true}).code === 0) {
        log.subhead('The tag "' + options.tag + '" already exists on remote. Skipping tagging.');
        return;
      }

      log.subhead('Tagging the local repository with ' + options.tag);
      execWrap('git tag ' + options.tag);
    }
280461
def main():
    
    from datetime import datetime

    # Initialize Command-Line and User-Config Settings, Log
    # -----------------------------------------------------

    beg_time = datetime.now()
    # Process command-line arguments to determine action
    # If no subcommand (e.g. 'import') is given, returns 'None' --> exit
    args, sub_clargs = load_command_line_args()
    if args is None:
        return

    # Create a logging object
    log = load_log(args)

    # Run configuration/setup interactive script
    if args.command == 'setup':
        setup_user_config(log)
        return

    # Make sure configuration file exists, or that's what we're doing
    # (with the 'setup' subcommand)
    if not os.path.isfile(_CONFIG_PATH):
        raise RuntimeError("'{}' does not exist.  "
                           "Run `astrocats setup` to configure."
                           "".format(_CONFIG_PATH))

    git_vers = get_git()
    title_str = "Astrocats, version: {}, SHA: {}".format(__version__, git_vers)
    log.warning("\n\n{}\n{}\n{}\n".format(title_str, '=' * len(title_str),
                                          beg_time.ctime()))

    # Load the user settings from the home directory
    args = load_user_config(args, log)

    # Choose Catalog and Operation(s) to perform
    # ------------------------------------------
    mod_name = args.command
    log.debug("Importing specified module: '{}'".format(mod_name))
    # Try to import the specified module
    try:
        mod = importlib.import_module('.' + mod_name, package='astrocats')
    except Exception as err:
        log.error("Import of specified module '{}' failed.".format(mod_name))
        log_raise(log, str(err), type(err))

    # Run the `main.main` method of the specified module
    log.debug("Running `main.main()`")
    mod.main.main(args, sub_clargs, log)

    end_time = datetime.now()
    log.warning("\nAll complete at {}, After {}".format(end_time, end_time -
                                                        beg_time))
    return
1076087
def main():
    
    # see:
    # https://packaging.python.org/tutorials/distributing-packages/#uploading-your-project-to-pypi
    twine_repo = os.getenv('TWINE_REPOSITORY_URL') or os.getenv('TWINE_REPOSITORY')
    print('tagging and releasing to %s as %s' % (
        twine_repo,
        os.getenv('TWINE_USERNAME')
    ))

    if not twine_repo:
        raise Exception('cannot release to implicit pypi repository. explicitly set the repo/url.')

    version = subprocess.check_output(['pipenv', 'run', 'python', 'setup.py', '--version']).decode().strip()
    if 'dev' in version:
        raise Exception('cannot release unversioned project: %s' % version)

    print('Preparing environment')
    subprocess.check_call(['git', 'config', '--global', 'user.name', 'monty-bot'])
    subprocess.check_call(['git', 'config', '--global', 'user.email', 'monty-bot@arm.com'])
    url = subprocess.check_output(['git', 'remote', 'get-url', 'origin'])
    branch_name = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
    new_url = git_url_ssh_to_https(url.decode())
    subprocess.check_call(['git', 'remote', 'set-url', 'origin', new_url])
    branch_spec = 'origin/%s' % branch_name.decode('utf-8').strip()
    subprocess.check_call(['git', 'branch', '--set-upstream-to', branch_spec])
    print('Committing the changelog & version')
    subprocess.check_call(['git', 'add', 'src/auto_version/__version__.py'])
    subprocess.check_call(['git', 'add', 'CHANGELOG.md'])
    subprocess.check_call(['git', 'add', 'docs/news/*'])
    message = ':checkered_flag: :newspaper: Releasing version %s\n[skip ci]' % version
    subprocess.check_call(['git', 'commit', '-m', message])
    print('Tagging the project')
    subprocess.check_call(['git', 'tag', '-a', version, '-m', 'Release %s' % version])
    print('Pushing changes back to GitHub')
    subprocess.check_call(['git', 'push', '--follow-tags'])
    print('Marking this commit as latest')
    subprocess.check_call(['git', 'tag', '-f', 'latest'])
    subprocess.check_call(['git', 'push', '-f', '--tags'])
    print('Generating a release package')
    subprocess.check_call(
        ['pipenv', 'run', 'python', 'setup.py', 'clean', '--all', 'bdist_wheel', '--dist-dir', 'release-dist'])
    print('Uploading to PyPI')
    subprocess.check_call(['pipenv', 'run', 'python', '-m', 'twine', 'upload', 'release-dist/*'])
    print('Done.')