From 6034a07901bdf5cccac21586c0eb9db96087af1a Mon Sep 17 00:00:00 2001 From: random-geek <35757396+random-geek@users.noreply.github.com> Date: Wed, 1 Jul 2020 16:34:44 -0700 Subject: [PATCH] Switch to proper setuptools-based structure. --- .gitignore | 138 +++++++++++++++++++++++++++++++ README.md | 19 ++++- lib/__init__.py | 0 mapedit/__init__.py | 5 ++ {lib => mapedit}/blockfuncs.py | 0 mapedit.py => mapedit/cmdline.py | 83 ++++++++++--------- {lib => mapedit}/commands.py | 0 {lib => mapedit}/mapblock.py | 0 {lib => mapedit}/utils.py | 0 setup.py | 28 +++++++ 10 files changed, 230 insertions(+), 43 deletions(-) create mode 100644 .gitignore delete mode 100644 lib/__init__.py create mode 100644 mapedit/__init__.py rename {lib => mapedit}/blockfuncs.py (100%) rename mapedit.py => mapedit/cmdline.py (60%) rename {lib => mapedit}/commands.py (100%) rename {lib => mapedit}/mapblock.py (100%) rename {lib => mapedit}/utils.py (100%) create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a81c8ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,138 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ diff --git a/README.md b/README.md index be8d98c..b9845d2 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,21 @@ MapEdit is a command-line tool written in Python for relatively fast manipulatio MapEdit is currently in the beta stage, and like any code, it may have bugs. Use it at your own risk. -## Requirements +## Installation -- Python 3 (If you don't already have it, download it from [python.org](https://www.python.org).) -- NumPy, which can be installed with `pip install numpy`. +MapEdit required Python 3.8 or higher. NumPy will also be installed if it isn't already. + +First, download MapEdit from [here](https://github.com/random-geek/MapEdit/archive/master.zip) or by using `git clone`. +If you downloaded the zip file, unzip it into a new directory. + +Then, open a terminal/command prompt/PowerShell window in the MapEdit directory and run: + +``` +pip install --upgrade setuptools +python setup.py install +``` + +This will install MapEdit as a script/executable which can be run from anywhere. ## Usage @@ -24,7 +35,7 @@ Most commands require mapblocks to be already generated to work. This can be ach #### General usage -`python mapedit.py [-h] -f [--no-warnings] ` +`mapedit [-h] -f [--no-warnings] ` #### Arguments diff --git a/lib/__init__.py b/lib/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/mapedit/__init__.py b/mapedit/__init__.py new file mode 100644 index 0000000..df452e6 --- /dev/null +++ b/mapedit/__init__.py @@ -0,0 +1,5 @@ +"""Edit Minetest map database files.""" + +__version__ = "0.1.0-dev" +__author__ = "random-geek" +__license__ = "LGPL-3.0" diff --git a/lib/blockfuncs.py b/mapedit/blockfuncs.py similarity index 100% rename from lib/blockfuncs.py rename to mapedit/blockfuncs.py diff --git a/mapedit.py b/mapedit/cmdline.py similarity index 60% rename from mapedit.py rename to mapedit/cmdline.py index bbc20e3..e27a209 100644 --- a/mapedit.py +++ b/mapedit/cmdline.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python3 import argparse -from lib import commands -# TODO: Fix file structure, add setuptools? +from . import commands, __version__ + +# Define arguments. ARGUMENT_DEFS = { "p1": { "always_opt": True, @@ -116,48 +116,53 @@ ARGUMENT_DEFS = { }, } -# Initialize parsers. -parser = argparse.ArgumentParser( - description="Edit Minetest map database files.", - epilog="Run `mapedit.py -h` for command-specific help.") +def run_cmdline(): + """Run MapEdit as a command-line script.""" -parser.add_argument("-f", - required=True, - dest="file", - metavar="", - help="Path to primary map file") -parser.add_argument("--no-warnings", - dest="no_warnings", - action="store_true", - help="Don't show warnings or confirmation prompts.") + # Initialize parsers. + parser = argparse.ArgumentParser( + description="Edit Minetest map database files.", + epilog="Run `mapedit.py -h` for command-specific help.") -subparsers = parser.add_subparsers(dest="command", required=True, - help="Command (see README.md for more information)") + parser.add_argument("-f", + required=True, + dest="file", + metavar="", + help="Path to primary map file") + parser.add_argument("--no-warnings", + dest="no_warnings", + action="store_true", + help="Don't show warnings or confirmation prompts.") + parser.add_argument("--version", + action="version", + version="%(prog)s " + __version__) -for cmdName, cmdDef in commands.COMMAND_DEFS.items(): - subparser = subparsers.add_parser(cmdName, help=cmdDef["help"]) + subparsers = parser.add_subparsers(dest="command", required=True, + help="Command (see README.md for more information)") - for arg, required in cmdDef["args"].items(): - argsToAdd = ("p1", "p2") if arg == "area" else (arg,) + for cmdName, cmdDef in commands.COMMAND_DEFS.items(): + subparser = subparsers.add_parser(cmdName, help=cmdDef["help"]) - for argToAdd in argsToAdd: - argDef = ARGUMENT_DEFS[argToAdd] + for arg, required in cmdDef["args"].items(): + argsToAdd = ("p1", "p2") if arg == "area" else (arg,) - if "always_opt" in argDef and argDef["always_opt"]: - # Always use an option flag, even if not required. - subparser.add_argument("--" + argToAdd, required=required, - **argDef["params"]) - else: - if required: - subparser.add_argument(argToAdd, **argDef["params"]) - else: - subparser.add_argument("--" + argToAdd, required=False, + for argToAdd in argsToAdd: + argDef = ARGUMENT_DEFS[argToAdd] + + if "always_opt" in argDef and argDef["always_opt"]: + # Always use an option flag, even if not required. + subparser.add_argument("--" + argToAdd, required=required, **argDef["params"]) + else: + if required: + subparser.add_argument(argToAdd, **argDef["params"]) + else: + subparser.add_argument("--" + argToAdd, required=False, + **argDef["params"]) -# Handle the actual command. - -args = commands.MapEditArgs() -parser.parse_args(namespace=args) -inst = commands.MapEditInstance() -inst.run(args) + # Handle the actual command. + args = commands.MapEditArgs() + parser.parse_args(namespace=args) + inst = commands.MapEditInstance() + inst.run(args) diff --git a/lib/commands.py b/mapedit/commands.py similarity index 100% rename from lib/commands.py rename to mapedit/commands.py diff --git a/lib/mapblock.py b/mapedit/mapblock.py similarity index 100% rename from lib/mapblock.py rename to mapedit/mapblock.py diff --git a/lib/utils.py b/mapedit/utils.py similarity index 100% rename from lib/utils.py rename to mapedit/utils.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..e310f56 --- /dev/null +++ b/setup.py @@ -0,0 +1,28 @@ +import setuptools +import mapedit + + +def get_long_desc(): + with open("README.md", "r") as f: + return f.read() + + +setuptools.setup( + name="mapedit", + version=mapedit.__version__, + description=mapedit.__doc__.strip(), + long_description=get_long_desc(), + long_description_content_type="text/markdown", + author=mapedit.__author__, + url="https://github.com/random-geek/MapEdit", + license=mapedit.__license__, + + packages=setuptools.find_packages(), + entry_points={ + "console_scripts": [ + "mapedit = mapedit.cmdline:run_cmdline" + ] + }, + python_requires=">=3.8", + install_requires="numpy" +)