stewbeet 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of stewbeet might be problematic. Click here for more details.

Files changed (136) hide show
  1. stewbeet-0.0.1/.gitignore +11 -0
  2. stewbeet-0.0.1/LICENSE +21 -0
  3. stewbeet-0.0.1/PKG-INFO +44 -0
  4. stewbeet-0.0.1/README.md +21 -0
  5. stewbeet-0.0.1/pyproject.toml +47 -0
  6. stewbeet-0.0.1/stewbeet/__init__.py +1 -0
  7. stewbeet-0.0.1/stewbeet/__main__.py +4 -0
  8. stewbeet-0.0.1/stewbeet/cli.py +76 -0
  9. stewbeet-0.0.1/stewbeet/continuous_delivery/__init__.py +8 -0
  10. stewbeet-0.0.1/stewbeet/continuous_delivery/cd_utils.py +27 -0
  11. stewbeet-0.0.1/stewbeet/continuous_delivery/github.py +3 -0
  12. stewbeet-0.0.1/stewbeet/continuous_delivery/modrinth.py +259 -0
  13. stewbeet-0.0.1/stewbeet/continuous_delivery/pmc.py +167 -0
  14. stewbeet-0.0.1/stewbeet/continuous_delivery/smithed.py +118 -0
  15. stewbeet-0.0.1/stewbeet/core/__init__.py +7 -0
  16. stewbeet-0.0.1/stewbeet/core/__memory__.py +20 -0
  17. stewbeet-0.0.1/stewbeet/core/constants.py +100 -0
  18. stewbeet-0.0.1/stewbeet/core/definitions_helper/__init__.py +11 -0
  19. stewbeet-0.0.1/stewbeet/core/definitions_helper/completion.py +108 -0
  20. stewbeet-0.0.1/stewbeet/core/definitions_helper/equipments.py +175 -0
  21. stewbeet-0.0.1/stewbeet/core/definitions_helper/materials.py +311 -0
  22. stewbeet-0.0.1/stewbeet/core/definitions_helper/records.py +105 -0
  23. stewbeet-0.0.1/stewbeet/core/definitions_helper/smart_ore_generation.py +206 -0
  24. stewbeet-0.0.1/stewbeet/core/definitions_helper/text.py +73 -0
  25. stewbeet-0.0.1/stewbeet/core/ingredients.py +226 -0
  26. stewbeet-0.0.1/stewbeet/core/utils/io.py +136 -0
  27. stewbeet-0.0.1/stewbeet/core/utils/sounds.py +67 -0
  28. stewbeet-0.0.1/stewbeet/dependencies/__init__.py +9 -0
  29. stewbeet-0.0.1/stewbeet/dependencies/bookshelf.py +31 -0
  30. stewbeet-0.0.1/stewbeet/dependencies/bookshelf_config.json +3 -0
  31. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Bitwise.zip +0 -0
  32. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Block.zip +0 -0
  33. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Color.zip +0 -0
  34. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Dump.zip +0 -0
  35. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Environment.zip +0 -0
  36. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Generation.zip +0 -0
  37. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Health.zip +0 -0
  38. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Hitbox.zip +0 -0
  39. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Id.zip +0 -0
  40. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Interaction.zip +0 -0
  41. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Link.zip +0 -0
  42. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Log.zip +0 -0
  43. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Math.zip +0 -0
  44. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Move.zip +0 -0
  45. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Position.zip +0 -0
  46. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Random.zip +0 -0
  47. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Raycast.zip +0 -0
  48. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Schedule.zip +0 -0
  49. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Sidebar.zip +0 -0
  50. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Spline.zip +0 -0
  51. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf String.zip +0 -0
  52. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Time.zip +0 -0
  53. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Tree.zip +0 -0
  54. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Vector.zip +0 -0
  55. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf View.zip +0 -0
  56. stewbeet-0.0.1/stewbeet/dependencies/datapack/Bookshelf Xp.zip +0 -0
  57. stewbeet-0.0.1/stewbeet/dependencies/datapack/Common Signals.zip +0 -0
  58. stewbeet-0.0.1/stewbeet/dependencies/datapack/Furnace NBT Recipes.zip +0 -0
  59. stewbeet-0.0.1/stewbeet/dependencies/datapack/ItemIO.zip +0 -0
  60. stewbeet-0.0.1/stewbeet/dependencies/datapack/SmartOreGeneration.zip +0 -0
  61. stewbeet-0.0.1/stewbeet/dependencies/datapack/Smithed Crafter.zip +0 -0
  62. stewbeet-0.0.1/stewbeet/dependencies/datapack/Smithed Custom Block.zip +0 -0
  63. stewbeet-0.0.1/stewbeet/dependencies/resource_pack/Smithed Crafter.zip +0 -0
  64. stewbeet-0.0.1/stewbeet/plugins/archive/__init__.py +118 -0
  65. stewbeet-0.0.1/stewbeet/plugins/auto/headers/__init__.py +82 -0
  66. stewbeet-0.0.1/stewbeet/plugins/auto/headers/object.py +150 -0
  67. stewbeet-0.0.1/stewbeet/plugins/auto/lang_file/__init__.py +37 -0
  68. stewbeet-0.0.1/stewbeet/plugins/auto/lang_file/utils.py +106 -0
  69. stewbeet-0.0.1/stewbeet/plugins/compatibilities/neo_enchant/__init__.py +31 -0
  70. stewbeet-0.0.1/stewbeet/plugins/compatibilities/simpledrawer/__init__.py +160 -0
  71. stewbeet-0.0.1/stewbeet/plugins/compute_sha1/__init__.py +34 -0
  72. stewbeet-0.0.1/stewbeet/plugins/copy_to_destination/__init__.py +174 -0
  73. stewbeet-0.0.1/stewbeet/plugins/custom_recipes/__init__.py +33 -0
  74. stewbeet-0.0.1/stewbeet/plugins/custom_recipes/furnace.py +171 -0
  75. stewbeet-0.0.1/stewbeet/plugins/custom_recipes/pulverizer.py +65 -0
  76. stewbeet-0.0.1/stewbeet/plugins/custom_recipes/smithed.py +187 -0
  77. stewbeet-0.0.1/stewbeet/plugins/custom_recipes/vanilla.py +215 -0
  78. stewbeet-0.0.1/stewbeet/plugins/datapack/custom_blocks/__init__.py +421 -0
  79. stewbeet-0.0.1/stewbeet/plugins/datapack/loading/__init__.py +108 -0
  80. stewbeet-0.0.1/stewbeet/plugins/datapack/loot_tables/__init__.py +153 -0
  81. stewbeet-0.0.1/stewbeet/plugins/finalyze/basic_datapack_structure/__init__.py +93 -0
  82. stewbeet-0.0.1/stewbeet/plugins/finalyze/check_unused_textures/__init__.py +58 -0
  83. stewbeet-0.0.1/stewbeet/plugins/finalyze/custom_blocks_ticking/__init__.py +92 -0
  84. stewbeet-0.0.1/stewbeet/plugins/finalyze/dependencies/__init__.py +233 -0
  85. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/__init__.py +51 -0
  86. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/furnace.png +0 -0
  87. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/heavy_workbench.png +0 -0
  88. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/invisible_item.png +0 -0
  89. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/invisible_item_release.png +0 -0
  90. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/minecraft_font.ttf +0 -0
  91. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/none.png +0 -0
  92. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/none_release.png +0 -0
  93. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/pulverizing.png +0 -0
  94. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/shaped_2x2.png +0 -0
  95. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/shaped_3x3.png +0 -0
  96. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/simple_case_no_border.png +0 -0
  97. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/wiki_information.png +0 -0
  98. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft.png +0 -0
  99. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft_template.png +0 -0
  100. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/assets/wiki_result_of_craft.png +0 -0
  101. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/book_components.py +119 -0
  102. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/book_optimizer.py +118 -0
  103. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/craft_content.py +189 -0
  104. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/image_utils.py +138 -0
  105. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/iso_renders.py +120 -0
  106. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/main.py +705 -0
  107. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/other_utils.py +127 -0
  108. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/page_font.py +201 -0
  109. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/shared_import.py +75 -0
  110. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/.gitignore +1 -0
  111. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/_README.md +5 -0
  112. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/furnace.png +0 -0
  113. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/heavy_workbench.png +0 -0
  114. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/invisible_item.png +0 -0
  115. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/invisible_item_release.png +0 -0
  116. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/minecraft_font.ttf +0 -0
  117. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/none.png +0 -0
  118. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/none_release.png +0 -0
  119. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/pulverizing.png +0 -0
  120. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/shaped_2x2.png +0 -0
  121. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/shaped_3x3.png +0 -0
  122. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/simple_case_no_border.png +0 -0
  123. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/wiki_information.png +0 -0
  124. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft.png +0 -0
  125. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft_template.png +0 -0
  126. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/templates/wiki_result_of_craft.png +0 -0
  127. stewbeet-0.0.1/stewbeet/plugins/ingame_manual/text_components.py +47 -0
  128. stewbeet-0.0.1/stewbeet/plugins/initialize/__init__.py +96 -0
  129. stewbeet-0.0.1/stewbeet/plugins/initialize/source_lore_font.py +61 -0
  130. stewbeet-0.0.1/stewbeet/plugins/merge_smithed_weld/__init__.py +44 -0
  131. stewbeet-0.0.1/stewbeet/plugins/merge_smithed_weld/weld.py +169 -0
  132. stewbeet-0.0.1/stewbeet/plugins/resource_pack/check_power_of_2/__init__.py +35 -0
  133. stewbeet-0.0.1/stewbeet/plugins/resource_pack/item_models/__init__.py +59 -0
  134. stewbeet-0.0.1/stewbeet/plugins/resource_pack/item_models/object.py +315 -0
  135. stewbeet-0.0.1/stewbeet/plugins/resource_pack/sounds/__init__.py +93 -0
  136. stewbeet-0.0.1/stewbeet/plugins/verify_definitions/__init__.py +216 -0
@@ -0,0 +1,11 @@
1
+
2
+ env
3
+ venv
4
+ .env
5
+ .venv
6
+ __pycache__
7
+ extensive_template/continuous_delivery/
8
+ upload.py
9
+ perf.html
10
+ .beet_cache
11
+
stewbeet-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Alexandre Collignon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,44 @@
1
+ Metadata-Version: 2.4
2
+ Name: stewbeet
3
+ Version: 0.0.1
4
+ Summary: Beet Framework made to help generating advanced Minecraft datapack contents
5
+ Project-URL: Homepage, https://github.com/Stoupy51/stewbeet
6
+ Project-URL: Issues, https://github.com/Stoupy51/stewbeet/issues
7
+ Author-email: Stoupy51 <stoupy51@gmail.com>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.12
14
+ Requires-Dist: beet>=0.110.1
15
+ Requires-Dist: bolt>=0.49.1
16
+ Requires-Dist: mecha>=0.98.1
17
+ Requires-Dist: model-resolver>=1.8.0
18
+ Requires-Dist: mutagen>=1.47.0
19
+ Requires-Dist: pyperclip>=1.8.0
20
+ Requires-Dist: smithed>=0.19.0
21
+ Requires-Dist: stouputils>=1.3.12
22
+ Description-Content-Type: text/markdown
23
+
24
+
25
+ # 📦 Package Link
26
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/stewbeet?logo=python&label=PyPI%20downloads)](https://pypi.org/project/stewbeet/)
27
+
28
+ # 🐍 StewBeet
29
+ Here is a template to a GitHub repository using this Python package: 📝
30
+ [https://github.com/Stoupy51/StewBeet](https://github.com/Stoupy51/StewBeet)
31
+
32
+ Here is an advanced example using this Python package: ⚡
33
+ [https://github.com/Stoupy51/SimplEnergy](https://github.com/Stoupy51/SimplEnergy)
34
+
35
+ ## ⭐ Star History
36
+
37
+ <a href="https://star-history.com/#Stoupy51/stewbeet&Date">
38
+ <picture>
39
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stewbeet&type=Date&theme=dark" />
40
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stewbeet&type=Date" />
41
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stewbeet&type=Date" />
42
+ </picture>
43
+ </a>
44
+
@@ -0,0 +1,21 @@
1
+
2
+ # 📦 Package Link
3
+ [![PyPI - Downloads](https://img.shields.io/pypi/dm/stewbeet?logo=python&label=PyPI%20downloads)](https://pypi.org/project/stewbeet/)
4
+
5
+ # 🐍 StewBeet
6
+ Here is a template to a GitHub repository using this Python package: 📝
7
+ [https://github.com/Stoupy51/StewBeet](https://github.com/Stoupy51/StewBeet)
8
+
9
+ Here is an advanced example using this Python package: ⚡
10
+ [https://github.com/Stoupy51/SimplEnergy](https://github.com/Stoupy51/SimplEnergy)
11
+
12
+ ## ⭐ Star History
13
+
14
+ <a href="https://star-history.com/#Stoupy51/stewbeet&Date">
15
+ <picture>
16
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stewbeet&type=Date&theme=dark" />
17
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Stoupy51/stewbeet&type=Date" />
18
+ <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Stoupy51/stewbeet&type=Date" />
19
+ </picture>
20
+ </a>
21
+
@@ -0,0 +1,47 @@
1
+
2
+ [build-system]
3
+ requires = ["hatchling"]
4
+ build-backend = "hatchling.build"
5
+
6
+ [project]
7
+ name = "stewbeet"
8
+ version = "0.0.1"
9
+ description = "Beet Framework made to help generating advanced Minecraft datapack contents"
10
+ readme = "README.md"
11
+ license = "MIT"
12
+ requires-python = ">=3.12"
13
+ classifiers = [
14
+ "Programming Language :: Python :: 3",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Operating System :: OS Independent",
17
+ ]
18
+ dependencies = [
19
+ "stouputils>=1.3.12",
20
+ "model_resolver>=1.8.0",
21
+ "beet>=0.110.1",
22
+ "bolt>=0.49.1",
23
+ "mecha>=0.98.1",
24
+ "smithed>=0.19.0",
25
+ "mutagen>=1.47.0",
26
+ "pyperclip>=1.8.0",
27
+ ]
28
+ [[project.authors]]
29
+ name = "Stoupy51"
30
+ email = "stoupy51@gmail.com"
31
+
32
+ [project.urls]
33
+ Homepage = "https://github.com/Stoupy51/stewbeet"
34
+ Issues = "https://github.com/Stoupy51/stewbeet/issues"
35
+
36
+ [project.scripts]
37
+ stewbeet = "stewbeet.cli:main"
38
+
39
+ [tool.pyright]
40
+ typeCheckingMode = "basic"
41
+
42
+ [tool.setuptools]
43
+ license-files = ["LICENSE"]
44
+
45
+ [tool.hatch.build]
46
+ include = ["stewbeet"]
47
+
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,4 @@
1
+
2
+ # Imports
3
+ from .cli import main # noqa: F401
4
+
@@ -0,0 +1,76 @@
1
+
2
+ # Imports
3
+ import importlib
4
+ import os
5
+ import shutil
6
+ import subprocess
7
+ import sys
8
+
9
+ from beet import ProjectConfig, load_config, locate_config
10
+ from box import Box
11
+ from stouputils.decorators import LogLevels, handle_error
12
+ from stouputils.io import clean_path
13
+ from stouputils.print import error, info
14
+
15
+
16
+ @handle_error(message="Error while running 'stewbeet'")
17
+ def main():
18
+ second_arg: str = sys.argv[1] if len(sys.argv) == 2 else ""
19
+
20
+ # Try to find and load the beet configuration file
21
+ cfg: ProjectConfig | None = None
22
+ if config_path := locate_config(os.getcwd(), parents=True):
23
+ cfg = load_config(filename=config_path)
24
+ if cfg:
25
+ os.chdir(config_path.parent)
26
+ if not cfg:
27
+ error(f"No beet config file found in the current directory '{clean_path(os.getcwd())}'")
28
+
29
+ # Check if the command is "clean" or "rebuild"
30
+ if second_arg in ["clean", "rebuild"]:
31
+ info("Cleaning project and caches...")
32
+
33
+ # Remove the beet cache directory
34
+ subprocess.run(["beet", "cache", "-c"], check=False, capture_output=True)
35
+ if os.path.exists(".beet_cache"):
36
+ shutil.rmtree(".beet_cache", ignore_errors=True)
37
+
38
+ # Remove the output directory specified in the config
39
+ shutil.rmtree(cfg.output, ignore_errors=True)
40
+
41
+ # Remove all __pycache__ folders
42
+ for root, dirs, _ in os.walk("."):
43
+ if "__pycache__" in dirs:
44
+ cache_dir: str = os.path.join(root, "__pycache__")
45
+ shutil.rmtree(cache_dir, ignore_errors=True)
46
+
47
+ # Load metadata from config into a Box
48
+ meta: Box = Box(cfg.meta, default_box=True, default_box_attr={})
49
+
50
+ # Remove manual cache directory if specified in metadata
51
+ cache_path: str = meta.stewbeet.manual.cache_path
52
+ if cache_path and os.path.exists(cache_path):
53
+ shutil.rmtree(cache_path, ignore_errors=True)
54
+
55
+ # Remove debug definitions file if it exists
56
+ definitions_debug: str = meta.stewbeet.definitions_debug
57
+ if definitions_debug and os.path.exists(definitions_debug):
58
+ os.remove(definitions_debug)
59
+ info("Cleaning done!")
60
+
61
+ if second_arg != "clean":
62
+ # Add current directory to Python path
63
+ current_dir: str = os.getcwd()
64
+ if current_dir not in sys.path:
65
+ sys.path.insert(0, current_dir)
66
+
67
+ # Try to import all pipeline
68
+ for plugin in cfg.pipeline:
69
+ handle_error(importlib.import_module, error_log=LogLevels.ERROR_TRACEBACK)(plugin)
70
+
71
+ # Run beet with all remaining arguments
72
+ subprocess.run(["beet"] + [x for x in sys.argv[1:] if x != "rebuild"], check=False)
73
+
74
+
75
+ if __name__ == "__main__":
76
+ main()
@@ -0,0 +1,8 @@
1
+
2
+ # Imports
3
+ from .cd_utils import *
4
+ from .github import *
5
+ from .modrinth import *
6
+ from .pmc import *
7
+ from .smithed import *
8
+
@@ -0,0 +1,27 @@
1
+
2
+ # Imports
3
+ import os
4
+
5
+ from stouputils.continuous_delivery.cd_utils import handle_response, load_credentials # noqa: F401
6
+
7
+ from ...stewbeet.core.constants import MINECRAFT_VERSION
8
+
9
+
10
+ # Function that replace the "~" by the user's home directory
11
+ def replace_tilde(path: str) -> str:
12
+ return path.replace("~", os.path.expanduser("~"))
13
+
14
+ # Supported versions
15
+ def get_supported_versions(version: str = MINECRAFT_VERSION) -> list[str]:
16
+ """ Get the supported versions for a given version of Minecraft
17
+
18
+ Args:
19
+ version (str): Version of Minecraft
20
+ Returns:
21
+ list[str]: List of supported versions, ex: ["1.21.3", "1.21.2"]
22
+ """
23
+ supported_versions: list[str] = [version]
24
+ if version == "1.21.3":
25
+ supported_versions.append("1.21.2")
26
+ return supported_versions
27
+
@@ -0,0 +1,3 @@
1
+
2
+ from stouputils.continuous_delivery.github import *
3
+
@@ -0,0 +1,259 @@
1
+
2
+ # Imports
3
+ import json
4
+ import os
5
+
6
+ import requests
7
+ import stouputils as stp
8
+
9
+ from .cd_utils import get_supported_versions, handle_response
10
+
11
+ # Constants
12
+ MODRINTH_API_URL: str = "https://api.modrinth.com/v2"
13
+ PROJECT_ENDPOINT: str = f"{MODRINTH_API_URL}/project"
14
+ VERSION_ENDPOINT: str = f"{MODRINTH_API_URL}/version"
15
+
16
+ def validate_credentials(credentials: dict[str, str]) -> str:
17
+ """ Get and validate Modrinth credentials
18
+
19
+ Args:
20
+ credentials (dict[str, str]): Credentials for the Modrinth API
21
+ Returns:
22
+ str: API key for Modrinth
23
+ """
24
+ if "modrinth_api_key" not in credentials:
25
+ raise ValueError("The credentials file must contain a 'modrinth_api_key' key, which is a PAT (Personal Access Token) for the Modrinth API: https://modrinth.com/settings/pats")
26
+ return credentials["modrinth_api_key"]
27
+
28
+ def validate_config(modrinth_config: dict[str, str]) -> tuple[str, str, str, str, str, str, str]:
29
+ """ Validate Modrinth configuration
30
+
31
+ Args:
32
+ modrinth_config (dict[str, str]): Configuration for the Modrinth project
33
+ Returns:
34
+ str: Project name on Modrinth
35
+ str: Version of the project
36
+ str: Slug (namespace) of the project
37
+ str: Summary of the project
38
+ str: Description in Markdown format
39
+ str: Version type (release, beta, alpha)
40
+ str: Build folder path
41
+ """
42
+ required_keys = [
43
+ "project_name", "version", "slug", "summary",
44
+ "description_markdown", "version_type", "build_folder"
45
+ ]
46
+ error_messages = {
47
+ "project_name": "name of the project on Modrinth",
48
+ "version": "version of the project",
49
+ "slug": "namespace of the project",
50
+ "summary": "summary of the project",
51
+ "description_markdown": "description of the project in Markdown format",
52
+ "version_type": "version type of the project (release, beta, alpha)",
53
+ "build_folder": "folder containing the build of the project (datapack and resourcepack zip files)"
54
+ }
55
+
56
+ for key in required_keys:
57
+ if key not in modrinth_config:
58
+ raise ValueError(f"The modrinth_config dictionary must contain a '{key}' key, which is the {error_messages[key]}")
59
+
60
+ return (
61
+ modrinth_config["project_name"],
62
+ modrinth_config["version"],
63
+ modrinth_config["slug"],
64
+ modrinth_config["summary"],
65
+ modrinth_config["description_markdown"],
66
+ modrinth_config["version_type"],
67
+ modrinth_config["build_folder"]
68
+ )
69
+
70
+ def get_project(slug: str, headers: dict[str, str]) -> dict:
71
+ """ Get project from Modrinth
72
+
73
+ Args:
74
+ slug (str): Project slug/namespace
75
+ headers (dict[str, str]): Headers for Modrinth API requests
76
+ Returns:
77
+ dict: Project data
78
+ """
79
+ stp.progress(f"Getting project {slug} from Modrinth")
80
+ search_response = requests.get(f"{PROJECT_ENDPOINT}/{slug}", headers=headers)
81
+ handle_response(search_response, f"Project not found on Modrinth, with namespace {slug}, please create it manually on https://modrinth.com/")
82
+ return search_response.json()
83
+
84
+ def update_project_description(slug: str, description: str, summary: str, headers: dict[str, str]) -> None:
85
+ """ Update project description and summary
86
+
87
+ Args:
88
+ slug (str): Project slug/namespace
89
+ description (str): Project description in Markdown
90
+ summary (str): Project summary
91
+ headers (dict[str, str]): Headers for Modrinth API requests
92
+ """
93
+ stp.progress("Updating project description")
94
+ update_response = requests.patch(
95
+ f"{PROJECT_ENDPOINT}/{slug}",
96
+ headers=headers,
97
+ json={"body": description.strip(), "description": summary.strip()}
98
+ )
99
+ handle_response(update_response, "Failed to update project description")
100
+
101
+ def handle_existing_version(slug: str, version: str, headers: dict[str, str]) -> bool:
102
+ """ Check and handle existing version
103
+
104
+ Args:
105
+ slug (str): Project slug/namespace
106
+ version (str): Version to check
107
+ headers (dict[str, str]): Headers for Modrinth API requests
108
+ Returns:
109
+ bool: True if we should continue, False otherwise
110
+ """
111
+ version_response = requests.get(f"{PROJECT_ENDPOINT}/{slug}/version/{version}", headers=headers)
112
+ if version_response.status_code == 200:
113
+ stp.warning(f"Version {version} already exists on Modrinth, do you want to delete it? (y/N)")
114
+ if input().lower() != "y":
115
+ return False
116
+ version_id: str = version_response.json()["id"]
117
+ delete_response = requests.delete(f"{VERSION_ENDPOINT}/{version_id}", headers=headers)
118
+ handle_response(delete_response, "Failed to delete the version")
119
+ elif version_response.status_code == 404:
120
+ stp.info(f"Version {version} not found on Modrinth, uploading...")
121
+ else:
122
+ stp.handle_response(version_response, "Failed to check if the version already exists")
123
+ return True
124
+
125
+ def get_file_parts(project_name: str, build_folder: str) -> list[str]:
126
+ """ Get file parts to upload
127
+
128
+ Args:
129
+ project_name (str): Name of the project
130
+ build_folder (str): Path to build folder
131
+ Returns:
132
+ list[str]: List of file paths to upload
133
+ """
134
+ file_parts: list[str] = [
135
+ f"{build_folder}/{project_name}_datapack_with_libs.zip",
136
+ f"{build_folder}/{project_name}_resource_pack_with_libs.zip"
137
+ ]
138
+ file_parts = [file_part for file_part in file_parts if os.path.exists(file_part)]
139
+ if len(file_parts) == 0:
140
+ file_parts = [
141
+ f"{build_folder}/{project_name}_datapack.zip",
142
+ f"{build_folder}/{project_name}_resource_pack.zip"
143
+ ]
144
+ file_parts = [file_part for file_part in file_parts if os.path.exists(file_part)]
145
+ if len(file_parts) == 0:
146
+ raise ValueError(f"No file parts (datapack and resourcepack zip files) found in {build_folder}, please check the build_folder path in the modrinth_config file")
147
+ return file_parts
148
+
149
+ def upload_version(
150
+ project_id: str,
151
+ project_name: str,
152
+ version: str,
153
+ version_type: str,
154
+ changelog: str,
155
+ file_parts: list[str],
156
+ headers: dict[str, str],
157
+ dependencies: list[str] | None = None
158
+ ) -> dict:
159
+ """ Upload new version
160
+
161
+ Args:
162
+ project_id (str): Modrinth project ID
163
+ project_name (str): Name of the project
164
+ version (str): Version number
165
+ version_type (str): Type of version (release, beta, alpha)
166
+ changelog (str): Changelog text
167
+ file_parts (list[str]): List of files to upload
168
+ headers (dict[str, str]): Headers for Modrinth API requests
169
+ dependencies (list[str]): List of dependencies
170
+ Returns:
171
+ dict: Upload response data
172
+ """
173
+ if dependencies is None:
174
+ dependencies = []
175
+ stp.progress(f"Creating version {version}")
176
+ files: dict[str, bytes] = {}
177
+ for file_part in file_parts:
178
+ stp.progress(f"Reading file {os.path.basename(file_part)}")
179
+ with open(file_part, "rb") as file:
180
+ files[os.path.basename(file_part)] = file.read()
181
+
182
+ request_data: dict = {
183
+ "name": f"{project_name} [v{version}]",
184
+ "version_number": version,
185
+ "changelog": changelog,
186
+ "dependencies": dependencies,
187
+ "game_versions": get_supported_versions(),
188
+ "version_type": version_type,
189
+ "loaders": ["datapack"],
190
+ "featured": False,
191
+ "status": "listed",
192
+ "project_id": project_id,
193
+ "file_parts": [os.path.basename(file_part) for file_part in file_parts],
194
+ "primary_file": os.path.basename(file_parts[0])
195
+ }
196
+
197
+ upload_response = requests.post(
198
+ VERSION_ENDPOINT,
199
+ headers=headers,
200
+ data={"data": json.dumps(request_data)},
201
+ files=files,
202
+ timeout=10,
203
+ stream=False
204
+ )
205
+ json_response: dict = upload_response.json()
206
+ handle_response(upload_response, "Failed to upload the version")
207
+ return json_response
208
+
209
+ def set_resource_pack_required(version_id: str, resource_pack_hash: str, headers: dict[str, str]) -> None:
210
+ """ Set resource pack as required
211
+
212
+ Args:
213
+ version_id (str): ID of the version
214
+ resource_pack_hash (str): SHA1 hash of resource pack
215
+ headers (dict[str, str]): Headers for Modrinth API requests
216
+ """
217
+ stp.progress("Setting resource pack as required")
218
+ version_response = requests.patch(
219
+ f"{VERSION_ENDPOINT}/{version_id}",
220
+ headers=headers,
221
+ json={"file_types": [{"algorithm": "sha1", "hash": resource_pack_hash, "file_type": "required-resource-pack"}]}
222
+ )
223
+ handle_response(version_response, "Failed to put the resource pack as required")
224
+
225
+ @stp.measure_time(stp.progress, "Uploading to modrinth took")
226
+ @stp.handle_error()
227
+ def upload_to_modrinth(credentials: dict[str, str], modrinth_config: dict, changelog: str = "") -> None:
228
+ """ Upload the project to Modrinth using the credentials and the configuration
229
+
230
+ Args:
231
+ credentials (dict[str, str]): Credentials for the Modrinth API
232
+ modrinth_config (dict): Configuration for the Modrinth project
233
+ changelog (str): Changelog text for the release
234
+ """
235
+ api_key = validate_credentials(credentials)
236
+ headers: dict[str, str] = {"Authorization": api_key}
237
+
238
+ project_name, version, slug, summary, description_markdown, version_type, build_folder = validate_config(modrinth_config)
239
+
240
+ project = get_project(slug, headers)
241
+ update_project_description(slug, description_markdown, summary, headers)
242
+ can_continue: bool = handle_existing_version(slug, version, headers)
243
+ if not can_continue:
244
+ return
245
+
246
+ file_parts = get_file_parts(project_name, build_folder)
247
+
248
+ json_response = upload_version(
249
+ project["id"], project_name, version, version_type,
250
+ changelog, file_parts, headers, modrinth_config.get("dependencies", [])
251
+ )
252
+
253
+ if len(file_parts) > 1:
254
+ resource_pack_hash: str = json_response["files"][1]["hashes"]["sha1"]
255
+ set_resource_pack_required(json_response["id"], resource_pack_hash, headers)
256
+
257
+ stp.info(f"Project {project_name} updated on Modrinth!")
258
+
259
+