<img align="right" src="https://raw.githubusercontent.com/mcbeet/mecha/main/logo.png" alt="logo" width="76">
# Mecha
[![GitHub Actions](https://github.com/mcbeet/mecha/workflows/CI/badge.svg)](https://github.com/mcbeet/mecha/actions)
[![PyPI](https://img.shields.io/pypi/v/mecha.svg)](https://pypi.org/project/mecha/)
[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mecha.svg)](https://pypi.org/project/mecha/)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![Discord](https://img.shields.io/discord/900530660677156924?color=7289DA&label=discord&logo=discord&logoColor=fff)](https://discord.gg/98MdSGMm8j)
> A powerful Minecraft command library.
```python
from mecha import Mecha
mc = Mecha()
function = """
execute
as @a # For each "player",
at @s # start at their feet.
anchored eyes # Looking through their eyes,
facing 0 0 0 # face perfectly at the target
anchored feet # (go back to the feet)
positioned ^ ^ ^1 # and move one block forward.
rotated as @s # Face the direction the player
# is actually facing,
positioned ^ ^ ^-1 # and move one block back.
if entity @s[distance=..0.6] # Check if we're close to the
# player's feet.
run
say I'm facing the target!
"""
ast = mc.parse(function, multiline=True)
print(mc.serialize(ast)) # execute as @a at @s anchored eyes facing ...
```
## Introduction
This package provides everything you need for working with Minecraft commands in Python, whether you're looking to process commands or build abstractions on top.
### Features
- Extensible and version-agnostic `mcfunction` parser
- Clean, immutable and hashable abstract syntax tree with source location
- Command config resolver that flattens and enumerates all the valid command prototypes
- Powerful rule dispatcher for processing specific ast nodes
- Composable ast visitors and reducers
- Comes with useful syntactic extensions like relative locations, nesting and implicit execute
- Compile-time scripting with [Bolt](https://github.com/mcbeet/bolt), a subset of Python integrated into command syntax
- Rich function analyzer for keeping track of command statistics
- Execute arbitrary compilation passes in your [`beet`](https://github.com/mcbeet/beet) pipeline
- _(soon)_ Expressive command API for writing commands in Python
## Credits
- [A few test cases are adapted from `SPYGlass`](https://github.com/SPYGlassMC/SPYGlass)
- [Multiline example by `AjaxGb` (MCC discord)](https://discord.com/channels/154777837382008833/157097006500806656/539318174466703361)
- [Multiline syntax derived from the `hangman` plugin](https://github.com/mcbeet/beet/blob/main/beet/contrib/hangman.py)
- [Partially inspired by `Trident`](https://energyxxer.com/trident/)
## Installation
The package can be installed with `pip`.
```bash
$ pip install mecha
```
## Command-line utility
```bash
$ mecha --help
Usage: mecha [OPTIONS] [SOURCE]...
Validate data packs and .mcfunction files.
Options:
-m, --minecraft VERSION Minecraft version.
-l, --log LEVEL Configure output verbosity.
-s, --stats Collect statistics.
-j, --json FILENAME Output json.
-v, --version Show the version and exit.
-h, --help Show this message and exit.
```
You can use the command-line utility to check data packs and function files for errors. The command arguments can be zipped and unzipped data packs, individual function files, and if you specify a directory that's not a data pack it will recursively grab all the `.mcfunction` files in the directory. You can use the `--minecraft` option to select between versions `1.16`, `1.17`, and `1.18`.
```bash
$ mecha path/to/my_data_pack
Validating with mecha vX.X.X
ERROR | mecha Expected curly '}' but got bracket ']'.
| path/to/my_data_pack/data/demo/functions/foo.mcfunction:5:34
| 4 |
| 5 | say hello @a[scores={foo=1, bar=2]
| : ^
Error: Reported 1 error.
```
The `--stats` option will output a report that shows how many commands, selectors and scoreboards were used. You can also use the `--json` option to output the raw statistics in a json file.
```
INFO | stats Analyzed 1 function
| -------------------------------------------------------------------------------
| Total commands (1 behind execute) | 4
| -------------------------------------------------------------------------------
| /scoreboard | 3
| objectives add <objective> <criteria> | 1
| players set <targets> <objective> <score> | 1
| players operation <targets> <targetObjective> <o... | 1
| /setblock (1 behind execute) | 1
| /execute | 1
| if score <target> <targetObjective> matches <range>... | 1
| as <targets> <subcommand> | 1
| run <subcommand> | 1
| -------------------------------------------------------------------------------
| Total selectors | 3
| -------------------------------------------------------------------------------
| @e | 2
| [tag] | 2
| [scores] | 1
| @s | 1
| @e with missing or inverted type | 2
| -------------------------------------------------------------------------------
| Scoreboard objectives | 2
| -------------------------------------------------------------------------------
| my_consts (dummy) | 3
| 10 | 2
| foo | 3
```
## Github action
You can use `mecha` to check your data packs and function files for errors without having to install anything using the [`mcbeet/check-commands`](https://github.com/mcbeet/check-commands) github action.
```yml
# .github/workflows/check-commands.yml
name: Check commands
on: [push]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: mcbeet/check-commands@v1
with:
source: .
```
This allows you to make sure that your commands don't contain any error when you push to your repository. For more details check out the [action README](https://github.com/mcbeet/check-commands#usage).
## Contributing
Contributions are welcome. Make sure to first open an issue discussing the problem or the new feature before creating a pull request. The project uses [`poetry`](https://python-poetry.org/).
```bash
$ poetry install
```
You can run the tests with `poetry run pytest`.
```bash
$ poetry run pytest
```
The project must type-check with [`pyright`](https://github.com/microsoft/pyright). If you're using VSCode the [`pylance`](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) extension should report diagnostics automatically. You can also install the type-checker locally with `npm install` and run it from the command-line.
```bash
$ npm run watch
$ npm run check
```
The code follows the [`black`](https://github.com/psf/black) code style. Import statements are sorted with [`isort`](https://pycqa.github.io/isort/).
```bash
$ poetry run isort mecha tests
$ poetry run black mecha tests
$ poetry run black --check mecha tests
```
---
License - [MIT](https://github.com/mcbeet/mecha/blob/main/LICENSE)
Raw data
{
"_id": null,
"home_page": "https://github.com/mcbeet/mecha",
"name": "mecha",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "beet, minecraft, datapack, minecraft-commands, mcfunction",
"author": "Valentin Berlier",
"author_email": "berlier.v@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/f9/73/a0241a4bf3a6b9c5b3a10469ced5f9f55f2e8df48bf284b691d2887ad3ce/mecha-0.95.2.tar.gz",
"platform": null,
"description": "<img align=\"right\" src=\"https://raw.githubusercontent.com/mcbeet/mecha/main/logo.png\" alt=\"logo\" width=\"76\">\n\n# Mecha\n\n[![GitHub Actions](https://github.com/mcbeet/mecha/workflows/CI/badge.svg)](https://github.com/mcbeet/mecha/actions)\n[![PyPI](https://img.shields.io/pypi/v/mecha.svg)](https://pypi.org/project/mecha/)\n[![PyPI - Python Version](https://img.shields.io/pypi/pyversions/mecha.svg)](https://pypi.org/project/mecha/)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![Discord](https://img.shields.io/discord/900530660677156924?color=7289DA&label=discord&logo=discord&logoColor=fff)](https://discord.gg/98MdSGMm8j)\n\n> A powerful Minecraft command library.\n\n```python\nfrom mecha import Mecha\n\nmc = Mecha()\n\nfunction = \"\"\"\n execute\n as @a # For each \"player\",\n at @s # start at their feet.\n anchored eyes # Looking through their eyes,\n facing 0 0 0 # face perfectly at the target\n anchored feet # (go back to the feet)\n positioned ^ ^ ^1 # and move one block forward.\n rotated as @s # Face the direction the player\n # is actually facing,\n positioned ^ ^ ^-1 # and move one block back.\n if entity @s[distance=..0.6] # Check if we're close to the\n # player's feet.\n run\n say I'm facing the target!\n\"\"\"\n\nast = mc.parse(function, multiline=True)\nprint(mc.serialize(ast)) # execute as @a at @s anchored eyes facing ...\n```\n\n## Introduction\n\nThis package provides everything you need for working with Minecraft commands in Python, whether you're looking to process commands or build abstractions on top.\n\n### Features\n\n- Extensible and version-agnostic `mcfunction` parser\n- Clean, immutable and hashable abstract syntax tree with source location\n- Command config resolver that flattens and enumerates all the valid command prototypes\n- Powerful rule dispatcher for processing specific ast nodes\n- Composable ast visitors and reducers\n- Comes with useful syntactic extensions like relative locations, nesting and implicit execute\n- Compile-time scripting with [Bolt](https://github.com/mcbeet/bolt), a subset of Python integrated into command syntax\n- Rich function analyzer for keeping track of command statistics\n- Execute arbitrary compilation passes in your [`beet`](https://github.com/mcbeet/beet) pipeline\n- _(soon)_ Expressive command API for writing commands in Python\n\n## Credits\n\n- [A few test cases are adapted from `SPYGlass`](https://github.com/SPYGlassMC/SPYGlass)\n- [Multiline example by `AjaxGb` (MCC discord)](https://discord.com/channels/154777837382008833/157097006500806656/539318174466703361)\n- [Multiline syntax derived from the `hangman` plugin](https://github.com/mcbeet/beet/blob/main/beet/contrib/hangman.py)\n- [Partially inspired by `Trident`](https://energyxxer.com/trident/)\n\n## Installation\n\nThe package can be installed with `pip`.\n\n```bash\n$ pip install mecha\n```\n\n## Command-line utility\n\n```bash\n$ mecha --help\nUsage: mecha [OPTIONS] [SOURCE]...\n\n Validate data packs and .mcfunction files.\n\nOptions:\n -m, --minecraft VERSION Minecraft version.\n -l, --log LEVEL Configure output verbosity.\n -s, --stats Collect statistics.\n -j, --json FILENAME Output json.\n -v, --version Show the version and exit.\n -h, --help Show this message and exit.\n```\n\nYou can use the command-line utility to check data packs and function files for errors. The command arguments can be zipped and unzipped data packs, individual function files, and if you specify a directory that's not a data pack it will recursively grab all the `.mcfunction` files in the directory. You can use the `--minecraft` option to select between versions `1.16`, `1.17`, and `1.18`.\n\n```bash\n$ mecha path/to/my_data_pack\nValidating with mecha vX.X.X\n\nERROR | mecha Expected curly '}' but got bracket ']'.\n | path/to/my_data_pack/data/demo/functions/foo.mcfunction:5:34\n | 4 |\n | 5 | say hello @a[scores={foo=1, bar=2]\n | : ^\n\nError: Reported 1 error.\n```\n\nThe `--stats` option will output a report that shows how many commands, selectors and scoreboards were used. You can also use the `--json` option to output the raw statistics in a json file.\n\n```\nINFO | stats Analyzed 1 function\n | -------------------------------------------------------------------------------\n | Total commands (1 behind execute) | 4\n | -------------------------------------------------------------------------------\n | /scoreboard | 3\n | objectives add <objective> <criteria> | 1\n | players set <targets> <objective> <score> | 1\n | players operation <targets> <targetObjective> <o... | 1\n | /setblock (1 behind execute) | 1\n | /execute | 1\n | if score <target> <targetObjective> matches <range>... | 1\n | as <targets> <subcommand> | 1\n | run <subcommand> | 1\n | -------------------------------------------------------------------------------\n | Total selectors | 3\n | -------------------------------------------------------------------------------\n | @e | 2\n | [tag] | 2\n | [scores] | 1\n | @s | 1\n | @e with missing or inverted type | 2\n | -------------------------------------------------------------------------------\n | Scoreboard objectives | 2\n | -------------------------------------------------------------------------------\n | my_consts (dummy) | 3\n | 10 | 2\n | foo | 3\n```\n\n## Github action\n\nYou can use `mecha` to check your data packs and function files for errors without having to install anything using the [`mcbeet/check-commands`](https://github.com/mcbeet/check-commands) github action.\n\n```yml\n# .github/workflows/check-commands.yml\nname: Check commands\non: [push]\n\njobs:\n check:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n - uses: mcbeet/check-commands@v1\n with:\n source: .\n```\n\nThis allows you to make sure that your commands don't contain any error when you push to your repository. For more details check out the [action README](https://github.com/mcbeet/check-commands#usage).\n\n## Contributing\n\nContributions are welcome. Make sure to first open an issue discussing the problem or the new feature before creating a pull request. The project uses [`poetry`](https://python-poetry.org/).\n\n```bash\n$ poetry install\n```\n\nYou can run the tests with `poetry run pytest`.\n\n```bash\n$ poetry run pytest\n```\n\nThe project must type-check with [`pyright`](https://github.com/microsoft/pyright). If you're using VSCode the [`pylance`](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance) extension should report diagnostics automatically. You can also install the type-checker locally with `npm install` and run it from the command-line.\n\n```bash\n$ npm run watch\n$ npm run check\n```\n\nThe code follows the [`black`](https://github.com/psf/black) code style. Import statements are sorted with [`isort`](https://pycqa.github.io/isort/).\n\n```bash\n$ poetry run isort mecha tests\n$ poetry run black mecha tests\n$ poetry run black --check mecha tests\n```\n\n---\n\nLicense - [MIT](https://github.com/mcbeet/mecha/blob/main/LICENSE)\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A powerful Minecraft command library",
"version": "0.95.2",
"project_urls": {
"Documentation": "https://github.com/mcbeet/mecha",
"Homepage": "https://github.com/mcbeet/mecha",
"Repository": "https://github.com/mcbeet/mecha"
},
"split_keywords": [
"beet",
" minecraft",
" datapack",
" minecraft-commands",
" mcfunction"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "2386fa11198171f8fa90f74a6fb5768d6bd53f25d87517699f6be7903af0ec63",
"md5": "f091d56f7bc2364b7ffe36c40cb72a51",
"sha256": "8abbbc6eee9871d622bf9c90cd6c3217b8325966d546bb0ca229d1eb7b963eff"
},
"downloads": -1,
"filename": "mecha-0.95.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "f091d56f7bc2364b7ffe36c40cb72a51",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 162272,
"upload_time": "2024-07-26T17:17:43",
"upload_time_iso_8601": "2024-07-26T17:17:43.507896Z",
"url": "https://files.pythonhosted.org/packages/23/86/fa11198171f8fa90f74a6fb5768d6bd53f25d87517699f6be7903af0ec63/mecha-0.95.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "f973a0241a4bf3a6b9c5b3a10469ced5f9f55f2e8df48bf284b691d2887ad3ce",
"md5": "fe8291b04641b97d6c0ec27b24f86f26",
"sha256": "06ee6f80f9dc091617fdeef7c03ffbbf482d5ec07cceab6e9f31a72a4e8a1ed8"
},
"downloads": -1,
"filename": "mecha-0.95.2.tar.gz",
"has_sig": false,
"md5_digest": "fe8291b04641b97d6c0ec27b24f86f26",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 136006,
"upload_time": "2024-07-26T17:17:46",
"upload_time_iso_8601": "2024-07-26T17:17:46.151956Z",
"url": "https://files.pythonhosted.org/packages/f9/73/a0241a4bf3a6b9c5b3a10469ced5f9f55f2e8df48bf284b691d2887ad3ce/mecha-0.95.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-07-26 17:17:46",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "mcbeet",
"github_project": "mecha",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "mecha"
}