mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-22 15:37:45 +00:00
add release
This commit is contained in:
commit
dd2c500294
6
release/.env
Normal file
6
release/.env
Normal file
@ -0,0 +1,6 @@
|
||||
DIR="$( dirname "${BASH_SOURCE[0]}" )"
|
||||
ACTIVATE_DIR="$(if [ -f "$DIR/../venv.mitmproxy/bin/activate" ]; then echo 'bin'; else echo 'Scripts'; fi;)"
|
||||
if [ -z "$VIRTUAL_ENV" ] && [ -f "$DIR/../venv.mitmproxy/$ACTIVATE_DIR/activate" ]; then
|
||||
echo "Activating mitmproxy virtualenv..."
|
||||
source "$DIR/../venv.mitmproxy/$ACTIVATE_DIR/activate"
|
||||
fi
|
9
release/.gitignore
vendored
Normal file
9
release/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
.DS_Store
|
||||
MANIFEST
|
||||
*.py[cdo]
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
/build
|
||||
/dist
|
||||
/mitmproxy_rtool.egg-info
|
83
release/README.mkd
Normal file
83
release/README.mkd
Normal file
@ -0,0 +1,83 @@
|
||||
|
||||
General build and release utilities for the mitmproxy, netlib and pathod
|
||||
projects. These tools assume a directory structure with all repositories at the
|
||||
same level, for example:
|
||||
|
||||
/src
|
||||
/mitmproxy
|
||||
/netlib
|
||||
/pathod
|
||||
/release
|
||||
|
||||
|
||||
# Release policies
|
||||
|
||||
- By default, every release is a new minor (`0.x`) release and it will be
|
||||
pushed for all three projects.
|
||||
|
||||
- Only if an emergency bugfix is needed, we push a new `0.x.y` bugfix release
|
||||
for a single project. This matches with what we do in `setup.py`:
|
||||
|
||||
"netlib>=%s, <%s" % (version.MINORVERSION, version.NEXT_MINORVERSION)
|
||||
|
||||
|
||||
|
||||
# Release Checklist
|
||||
|
||||
## Check out release versions
|
||||
|
||||
- Check out the versions of pathod, netlib and mitmproxy due to be released
|
||||
|
||||
- Verify that repositories are in a clean state:
|
||||
|
||||
`./build git status`
|
||||
|
||||
- Ensure that the website style assets have been compiled for production, and
|
||||
synced to the docs.
|
||||
|
||||
- Render the docs, update CONTRIBUTORS file:
|
||||
|
||||
./build docs contributors
|
||||
|
||||
|
||||
## Test
|
||||
|
||||
- Test the source distributions:
|
||||
|
||||
./build test
|
||||
|
||||
This does the following:
|
||||
- creates a venv in release/venv
|
||||
- creates source distributions in release/release
|
||||
- installs the source distributions in the venv
|
||||
- and runs all installed tools
|
||||
|
||||
|
||||
## Release
|
||||
|
||||
- Make a release commit for all projects, tag and push it:
|
||||
|
||||
./build git commit -am "Release v0.13"
|
||||
./build git tag v0.13
|
||||
./build git push --tags
|
||||
|
||||
- Build the OSX binaries
|
||||
- Follow instructions in osx-binaries
|
||||
- Move to download dir:
|
||||
|
||||
mv ./tmp/osx-mitmproxy-VERSION.tar.gz ~/mitmproxy/www.mitmproxy.org/src/download
|
||||
|
||||
- Move all source distributions from `./dist` to the server:
|
||||
|
||||
mv ./dist/* ~/mitmproxy/www.mitmproxy.org/src/download
|
||||
|
||||
- Upload distributions in `./dist` to PyPI:
|
||||
|
||||
./build upload
|
||||
|
||||
You can test with [testpypi.python.org](https://testpypi.python.org/pypi) by passing `--repository test`.
|
||||
([more info](https://tom-christie.github.io/articles/pypi/))
|
||||
|
||||
- Now bump the version number to be ready for the next cycle
|
||||
|
||||
`./build set-version 0.13`
|
68
release/rtool.pem
Normal file
68
release/rtool.pem
Normal file
@ -0,0 +1,68 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,7A4E07094E1AC0B74BB3D172A73A62DB
|
||||
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAs0xeGx+bc+NCLGRJDr6y
|
||||
qv825685l1Tb6lhLvYVYUFJfcxL1V79ML13CO09TPxGTbmKw7iI33ef9N2mUHHVe
|
||||
24EjcSnYZ2Zx5zYIY4ejnDKCzM0md9XA3RpfTI9F3zGsJPt72veyHy6alCbF4NgX
|
||||
FgAvp2UJmWwTLnJj3oIEwfGJeEcQRKjCFjSJlHGxbB6L0MSCgRtDxwlBfinzkriZ
|
||||
0C8YyVv6u+DidHtobbZvwk/4uV3+KhoDfkpT2VE57a2KXr4c9Fekzr6szduFMkcI
|
||||
KPqKouOOnaiNjOoKofbZ5I6cB6qoMkh+ebJvfPuEYBwhHmDDhpdjdk5v3LkeD5kt
|
||||
0GtOaF5A3LbdZhgsC+1v1dHrL6Vndrb9KhO8ATHvlzJOonV73AoJFygp6upCvIt+
|
||||
tPUuy3VE0kjc2mJDDJr5V28pSBJ5r9uz1rXZWP+9aduR3M+RUGzHS7cUdsl+lHyQ
|
||||
TFQAQIDhWXyokMGqVZBm9xJ2KcDiQAEr5+kP0BrhPmBtfHSnLA1tIXlFcOqakvyQ
|
||||
q1cACMvwbkZpupTqMhCr2S4V9dKxnlO5EIWYJmme9moU/zu1KA0mcwqfnNeDOR2J
|
||||
6c3/x3E+AqBoFzDQb6LQ2Iw+9bkKWKgDml4paLPu/ot8vA2ZB9/mujFUvp/1MLuD
|
||||
5I1jQDXFbjAgAnaSyqyW368CAwEAAQ==
|
||||
-----END PUBLIC KEY-----
|
439
release/rtool.py
Normal file
439
release/rtool.py
Normal file
@ -0,0 +1,439 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import absolute_import, print_function, division
|
||||
from os.path import join
|
||||
import contextlib
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import re
|
||||
import shlex
|
||||
import runpy
|
||||
import zipfile
|
||||
import tarfile
|
||||
import platform
|
||||
import click
|
||||
import pysftp
|
||||
import fnmatch
|
||||
from six.moves import shlex_quote
|
||||
|
||||
# https://virtualenv.pypa.io/en/latest/userguide.html#windows-notes
|
||||
# scripts and executables on Windows go in ENV\Scripts\ instead of ENV/bin/
|
||||
if platform.system() == "Windows":
|
||||
VENV_BIN = "Scripts"
|
||||
else:
|
||||
VENV_BIN = "bin"
|
||||
|
||||
if platform.system() == "Windows":
|
||||
def Archive(name):
|
||||
a = zipfile.ZipFile(name, "w")
|
||||
a.add = a.write
|
||||
return a
|
||||
else:
|
||||
def Archive(name):
|
||||
return tarfile.open(name, "w:gz")
|
||||
|
||||
RELEASE_DIR = join(os.path.dirname(os.path.realpath(__file__)))
|
||||
DIST_DIR = join(RELEASE_DIR, "dist")
|
||||
ROOT_DIR = join(RELEASE_DIR, "..")
|
||||
|
||||
BUILD_DIR = join(RELEASE_DIR, "build")
|
||||
PYINSTALLER_TEMP = join(BUILD_DIR, "pyinstaller")
|
||||
PYINSTALLER_DIST = join(BUILD_DIR, "binaries")
|
||||
|
||||
VENV_DIR = join(BUILD_DIR, "venv")
|
||||
VENV_PIP = join(VENV_DIR, VENV_BIN, "pip")
|
||||
VENV_PYINSTALLER = join(VENV_DIR, VENV_BIN, "pyinstaller")
|
||||
|
||||
ALL_PROJECTS = {
|
||||
"netlib": {
|
||||
"tools": [],
|
||||
"vfile": join(ROOT_DIR, "netlib/netlib/version.py"),
|
||||
"dir": join(ROOT_DIR, "netlib"),
|
||||
"python_version": "py2.py3" # this is the format in wheel filenames
|
||||
},
|
||||
"pathod": {
|
||||
"tools": ["pathod", "pathoc"],
|
||||
"vfile": join(ROOT_DIR, "pathod/libpathod/version.py"),
|
||||
"dir": join(ROOT_DIR, "pathod"),
|
||||
"python_version": "py2"
|
||||
},
|
||||
"mitmproxy": {
|
||||
"tools": ["mitmproxy", "mitmdump", "mitmweb"],
|
||||
"vfile": join(ROOT_DIR, "mitmproxy/libmproxy/version.py"),
|
||||
"dir": join(ROOT_DIR, "mitmproxy"),
|
||||
"python_version": "py2"
|
||||
}
|
||||
}
|
||||
if platform.system() == "Windows":
|
||||
ALL_PROJECTS["mitmproxy"]["tools"].remove("mitmproxy")
|
||||
|
||||
projects = {}
|
||||
|
||||
|
||||
def get_version(project):
|
||||
return runpy.run_path(projects[project]["vfile"])["VERSION"]
|
||||
|
||||
|
||||
def get_snapshot_version(project):
|
||||
last_tag, tag_dist, commit = subprocess.check_output(
|
||||
["git", "describe", "--tags", "--long"],
|
||||
cwd=projects[project]["dir"]
|
||||
).strip().rsplit("-", 2)
|
||||
tag_dist = int(tag_dist)
|
||||
if tag_dist == 0:
|
||||
return get_version(project)
|
||||
else:
|
||||
return "{version}dev{tag_dist:04}-{commit}".format(
|
||||
version=get_version(project), # this should already be the next version
|
||||
tag_dist=tag_dist,
|
||||
commit=commit
|
||||
)
|
||||
|
||||
|
||||
def archive_name(project):
|
||||
platform_tag = {
|
||||
"Darwin": "osx",
|
||||
"Windows": "win32",
|
||||
"Linux": "linux"
|
||||
}.get(platform.system(), platform.system())
|
||||
if platform.system() == "Windows":
|
||||
ext = "zip"
|
||||
else:
|
||||
ext = "tar.gz"
|
||||
return "{project}-{version}-{platform}.{ext}".format(
|
||||
project=project,
|
||||
version=get_version(project),
|
||||
platform=platform_tag,
|
||||
ext=ext
|
||||
)
|
||||
|
||||
|
||||
def sdist_name(project):
|
||||
return "{project}-{version}.tar.gz".format(
|
||||
project=project,
|
||||
version=get_version(project)
|
||||
)
|
||||
|
||||
|
||||
def wheel_name(project):
|
||||
return "{project}-{version}-{py_version}-none-any.whl".format(
|
||||
project=project,
|
||||
version=get_version(project),
|
||||
py_version=projects[project]["python_version"]
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def empty_pythonpath():
|
||||
"""
|
||||
Make sure that the regular python installation is not on the python path,
|
||||
which would give us access to modules installed outside of our virtualenv.
|
||||
"""
|
||||
pythonpath = os.environ.get("PYTHONPATH", "")
|
||||
os.environ["PYTHONPATH"] = ""
|
||||
yield
|
||||
os.environ["PYTHONPATH"] = pythonpath
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def chdir(path):
|
||||
old_dir = os.getcwd()
|
||||
os.chdir(path)
|
||||
yield
|
||||
os.chdir(old_dir)
|
||||
|
||||
|
||||
@click.group(chain=True)
|
||||
@click.option(
|
||||
'--project', '-p',
|
||||
multiple=True, type=click.Choice(ALL_PROJECTS.keys()), default=ALL_PROJECTS.keys()
|
||||
)
|
||||
def cli(project):
|
||||
"""
|
||||
mitmproxy build tool
|
||||
"""
|
||||
for name in project:
|
||||
projects[name] = ALL_PROJECTS[name]
|
||||
|
||||
|
||||
@cli.command("contributors")
|
||||
def contributors():
|
||||
"""
|
||||
Update CONTRIBUTORS.md
|
||||
"""
|
||||
for project, conf in projects.items():
|
||||
with chdir(conf["dir"]):
|
||||
print("Updating %s/CONTRIBUTORS..." % project)
|
||||
contributors_data = subprocess.check_output(
|
||||
shlex.split("git shortlog -n -s")
|
||||
)
|
||||
with open("CONTRIBUTORS", "w") as f:
|
||||
f.write(contributors_data)
|
||||
|
||||
|
||||
@cli.command("set-version")
|
||||
@click.argument('version')
|
||||
def set_version(version):
|
||||
"""
|
||||
Update version information
|
||||
"""
|
||||
print("Update versions...")
|
||||
version = ", ".join(version.split("."))
|
||||
for p, conf in projects.items():
|
||||
print("Update %s..." % os.path.normpath(conf["vfile"]))
|
||||
with open(conf["vfile"], "rb") as f:
|
||||
content = f.read()
|
||||
new_content = re.sub(
|
||||
r"IVERSION\s*=\s*\([\d,\s]+\)", "IVERSION = (%s)" % version,
|
||||
content
|
||||
)
|
||||
with open(conf["vfile"], "wb") as f:
|
||||
f.write(new_content)
|
||||
|
||||
|
||||
def _git(project, args):
|
||||
print("%s> %s..." % (project, " ".join(shlex_quote(a) for a in args)))
|
||||
subprocess.check_call(
|
||||
["git"] + list(args),
|
||||
cwd=projects[project]["dir"]
|
||||
)
|
||||
|
||||
|
||||
@cli.command("git")
|
||||
@click.argument('args', nargs=-1, required=True)
|
||||
def git(args):
|
||||
"""
|
||||
Run a git command on every project
|
||||
"""
|
||||
for project, conf in projects.items():
|
||||
_git(project, args)
|
||||
print("")
|
||||
|
||||
|
||||
@cli.command("sdist")
|
||||
def sdist():
|
||||
"""
|
||||
Build a source distribution
|
||||
"""
|
||||
with empty_pythonpath():
|
||||
print("Building release...")
|
||||
if os.path.exists(DIST_DIR):
|
||||
shutil.rmtree(DIST_DIR)
|
||||
for project, conf in projects.items():
|
||||
print("Creating %s source distribution..." % project)
|
||||
subprocess.check_call(
|
||||
[
|
||||
"python", "./setup.py", "-q",
|
||||
"sdist", "--dist-dir", DIST_DIR, "--formats=gztar",
|
||||
"bdist_wheel", "--dist-dir", DIST_DIR,
|
||||
],
|
||||
cwd=conf["dir"]
|
||||
)
|
||||
|
||||
print("Creating virtualenv for test install...")
|
||||
if os.path.exists(VENV_DIR):
|
||||
shutil.rmtree(VENV_DIR)
|
||||
subprocess.check_call(["virtualenv", "-q", VENV_DIR])
|
||||
|
||||
with chdir(DIST_DIR):
|
||||
for project, conf in projects.items():
|
||||
print("Installing %s..." % project)
|
||||
subprocess.check_call([VENV_PIP, "install", "-q", sdist_name(project)])
|
||||
|
||||
print("Running binaries...")
|
||||
for project, conf in projects.items():
|
||||
for tool in conf["tools"]:
|
||||
tool = join(VENV_DIR, VENV_BIN, tool)
|
||||
print("> %s --version" % tool)
|
||||
print(subprocess.check_output([tool, "--version"]))
|
||||
|
||||
print("Virtualenv available for further testing:")
|
||||
print("source %s" % os.path.normpath(join(VENV_DIR, VENV_BIN, "activate")))
|
||||
|
||||
|
||||
@cli.command("bdist")
|
||||
@click.option("--use-existing-sdist/--no-use-existing-sdist", default=False)
|
||||
@click.argument("pyinstaller_version", envvar="PYINSTALLER_VERSION", default="PyInstaller~=3.1.1")
|
||||
@click.pass_context
|
||||
def bdist(ctx, use_existing_sdist, pyinstaller_version):
|
||||
"""
|
||||
Build a binary distribution
|
||||
"""
|
||||
if os.path.exists(PYINSTALLER_TEMP):
|
||||
shutil.rmtree(PYINSTALLER_TEMP)
|
||||
if os.path.exists(PYINSTALLER_DIST):
|
||||
shutil.rmtree(PYINSTALLER_DIST)
|
||||
|
||||
if not use_existing_sdist:
|
||||
ctx.invoke(sdist)
|
||||
|
||||
print("Installing PyInstaller...")
|
||||
subprocess.check_call([VENV_PIP, "install", "-q", pyinstaller_version])
|
||||
|
||||
for p, conf in projects.items():
|
||||
if conf["tools"]:
|
||||
with Archive(join(DIST_DIR, archive_name(p))) as archive:
|
||||
for tool in conf["tools"]:
|
||||
spec = join(conf["dir"], "release", "%s.spec" % tool)
|
||||
print("Building %s binary..." % tool)
|
||||
subprocess.check_call(
|
||||
[
|
||||
VENV_PYINSTALLER,
|
||||
"--clean",
|
||||
"--workpath", PYINSTALLER_TEMP,
|
||||
"--distpath", PYINSTALLER_DIST,
|
||||
# This is PyInstaller, so setting a
|
||||
# different log level obviously breaks it :-)
|
||||
# "--log-level", "WARN",
|
||||
spec
|
||||
]
|
||||
)
|
||||
|
||||
# Test if it works at all O:-)
|
||||
executable = join(PYINSTALLER_DIST, tool)
|
||||
if platform.system() == "Windows":
|
||||
executable += ".exe"
|
||||
print("> %s --version" % executable)
|
||||
subprocess.check_call([executable, "--version"])
|
||||
|
||||
archive.add(executable, os.path.basename(executable))
|
||||
print("Packed {}.".format(archive_name(p)))
|
||||
|
||||
|
||||
@cli.command("upload-release")
|
||||
@click.option('--username', prompt=True)
|
||||
@click.password_option(confirmation_prompt=False)
|
||||
@click.option('--repository', default="pypi")
|
||||
@click.option("--sdist/--no-sdist", default=True)
|
||||
@click.option("--wheel/--no-wheel", default=True)
|
||||
def upload_release(username, password, repository, sdist, wheel):
|
||||
"""
|
||||
Upload source distributions to PyPI
|
||||
"""
|
||||
for project in projects.keys():
|
||||
files = []
|
||||
if sdist:
|
||||
files.append(sdist_name(project))
|
||||
if wheel:
|
||||
files.append(wheel_name(project))
|
||||
for f in files:
|
||||
print("Uploading {} to {}...".format(f, repository))
|
||||
subprocess.check_call([
|
||||
"twine",
|
||||
"upload",
|
||||
"-u", username,
|
||||
"-p", password,
|
||||
"-r", repository,
|
||||
join(DIST_DIR, f)
|
||||
])
|
||||
|
||||
|
||||
@cli.command("upload-snapshot")
|
||||
@click.option("--host", envvar="SNAPSHOT_HOST", prompt=True)
|
||||
@click.option("--port", envvar="SNAPSHOT_PORT", type=int, default=22)
|
||||
@click.option("--user", envvar="SNAPSHOT_USER", prompt=True)
|
||||
@click.option("--private-key", default=join(RELEASE_DIR, "rtool.pem"))
|
||||
@click.option("--private-key-password", envvar="SNAPSHOT_PASS", prompt=True, hide_input=True)
|
||||
@click.option("--sdist/--no-sdist", default=False)
|
||||
@click.option("--wheel/--no-wheel", default=False)
|
||||
@click.option("--bdist/--no-bdist", default=False)
|
||||
def upload_snapshot(host, port, user, private_key, private_key_password, sdist, wheel, bdist):
|
||||
"""
|
||||
Upload snapshot to snapshot server
|
||||
"""
|
||||
with pysftp.Connection(host=host,
|
||||
port=port,
|
||||
username=user,
|
||||
private_key=private_key,
|
||||
private_key_pass=private_key_password) as sftp:
|
||||
for project, conf in projects.items():
|
||||
dir_name = "snapshots/v{}".format(get_version(project))
|
||||
sftp.makedirs(dir_name)
|
||||
with sftp.cd(dir_name):
|
||||
files = []
|
||||
if sdist:
|
||||
files.append(sdist_name(project))
|
||||
if wheel:
|
||||
files.append(wheel_name(project))
|
||||
if bdist and conf["tools"]:
|
||||
files.append(archive_name(project))
|
||||
|
||||
for f in files:
|
||||
local_path = join(DIST_DIR, f)
|
||||
remote_filename = f.replace(get_version(project), get_snapshot_version(project))
|
||||
symlink_path = "../{}".format(f.replace(get_version(project), "latest"))
|
||||
|
||||
old_version = f.replace(get_version(project), "*")
|
||||
for f in sftp.listdir():
|
||||
if fnmatch.fnmatch(f, old_version):
|
||||
print("Removing {}...".format(f))
|
||||
sftp.remove(f)
|
||||
|
||||
print("Uploading {} as {}...".format(f, remote_filename))
|
||||
with click.progressbar(length=os.stat(local_path).st_size) as bar:
|
||||
sftp.put(
|
||||
local_path,
|
||||
"." + remote_filename,
|
||||
callback=lambda done, total: bar.update(done - bar.pos)
|
||||
)
|
||||
# We hide the file during upload.
|
||||
sftp.rename("." + remote_filename, remote_filename)
|
||||
|
||||
# add symlink
|
||||
if sftp.lexists(symlink_path):
|
||||
print("Removing {}...".format(symlink_path))
|
||||
sftp.remove(symlink_path)
|
||||
sftp.symlink("v{}/{}".format(get_version(project), remote_filename), symlink_path)
|
||||
|
||||
|
||||
@cli.command("wizard")
|
||||
@click.option('--next-version', prompt=True)
|
||||
@click.option('--username', prompt="PyPI Username")
|
||||
@click.password_option(confirmation_prompt=False, prompt="PyPI Password")
|
||||
@click.option('--repository', default="pypi")
|
||||
@click.pass_context
|
||||
def wizard(ctx, next_version, username, password, repository):
|
||||
"""
|
||||
Interactive Release Wizard
|
||||
"""
|
||||
for project, conf in projects.items():
|
||||
is_dirty = subprocess.check_output(["git", "status", "--porcelain"], cwd=conf["dir"])
|
||||
if is_dirty:
|
||||
raise RuntimeError("%s repository is not clean." % project)
|
||||
|
||||
# update contributors file
|
||||
ctx.invoke(contributors)
|
||||
|
||||
# Build test release
|
||||
ctx.invoke(bdist)
|
||||
|
||||
try:
|
||||
click.confirm("Please test the release now. Is it ok?", abort=True)
|
||||
except click.Abort:
|
||||
# undo changes
|
||||
ctx.invoke(git, args=["checkout", "CONTRIBUTORS"])
|
||||
raise
|
||||
|
||||
# Everything ok - let's ship it!
|
||||
for p in projects.keys():
|
||||
_git(p, ["tag", "v" + get_version(p)])
|
||||
ctx.invoke(git, args=["push", "--tags"])
|
||||
ctx.invoke(
|
||||
upload_release,
|
||||
username=username, password=password, repository=repository
|
||||
)
|
||||
|
||||
click.confirm("Now please wait until CI has built binaries. Finished?")
|
||||
|
||||
# version bump commit
|
||||
ctx.invoke(set_version, version=next_version)
|
||||
ctx.invoke(
|
||||
git, args=["commit", "-a", "-m", "bump version"]
|
||||
)
|
||||
ctx.invoke(git, args=["push"])
|
||||
|
||||
click.echo("All done!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
20
release/setup.py
Normal file
20
release/setup.py
Normal file
@ -0,0 +1,20 @@
|
||||
from setuptools import setup
|
||||
|
||||
setup(
|
||||
name='mitmproxy-rtool',
|
||||
version="1.0",
|
||||
py_modules=["rtool"],
|
||||
install_requires=[
|
||||
"click>=6.2, <7.0",
|
||||
"twine>=1.6.5, <1.7",
|
||||
"virtualenv>=14.0.5, <14.1",
|
||||
"wheel>=0.29.0, <0.30",
|
||||
"six>=1.10.0, <1.11",
|
||||
"pysftp>=0.2.8, <0.3",
|
||||
],
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"rtool=rtool:cli",
|
||||
],
|
||||
},
|
||||
)
|
Loading…
Reference in New Issue
Block a user