modsmith 0.1.0__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.
- modsmith-0.1.0/.editorconfig +15 -0
- modsmith-0.1.0/.gitattributes +4 -0
- modsmith-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +23 -0
- modsmith-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +13 -0
- modsmith-0.1.0/.github/dependabot.yml +18 -0
- modsmith-0.1.0/.github/pull_request_template.md +7 -0
- modsmith-0.1.0/.github/workflows/ci.yml +123 -0
- modsmith-0.1.0/.github/workflows/docs.yml +45 -0
- modsmith-0.1.0/.github/workflows/live.yml +33 -0
- modsmith-0.1.0/.github/workflows/release.yml +64 -0
- modsmith-0.1.0/.gitignore +34 -0
- modsmith-0.1.0/.pre-commit-config.yaml +22 -0
- modsmith-0.1.0/.python-version +1 -0
- modsmith-0.1.0/CHANGELOG.md +34 -0
- modsmith-0.1.0/CONTRIBUTING.md +117 -0
- modsmith-0.1.0/LICENSE +21 -0
- modsmith-0.1.0/PKG-INFO +285 -0
- modsmith-0.1.0/README.md +269 -0
- modsmith-0.1.0/README_ZH.md +269 -0
- modsmith-0.1.0/docs/_templates/404.html +19 -0
- modsmith-0.1.0/docs/_templates/autosummary/base.rst +7 -0
- modsmith-0.1.0/docs/_templates/autosummary/class.rst +6 -0
- modsmith-0.1.0/docs/_theme/modsmith/layout.html +104 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/chakra-petch-400.woff2 +0 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/chakra-petch-600.woff2 +0 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/chakra-petch-700.woff2 +0 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/chakra-petch-LICENSE.txt +93 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/fira-code-LICENSE.txt +93 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/fira-code.woff2 +0 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/modsmith.css +1972 -0
- modsmith-0.1.0/docs/_theme/modsmith/static/modsmith.js +151 -0
- modsmith-0.1.0/docs/_theme/modsmith/theme.toml +8 -0
- modsmith-0.1.0/docs/assets/banner.svg +12 -0
- modsmith-0.1.0/docs/assets/hero-small.svg +12 -0
- modsmith-0.1.0/docs/assets/hero.svg +12 -0
- modsmith-0.1.0/docs/assets/logo.svg +1 -0
- modsmith-0.1.0/docs/assets/pixel/LICENSE.txt +21 -0
- modsmith-0.1.0/docs/assets/pixel/alert.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/block.svg +4 -0
- modsmith-0.1.0/docs/assets/pixel/bulb.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/check.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/clock.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/cup.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/download.svg +5 -0
- modsmith-0.1.0/docs/assets/pixel/flag.svg +4 -0
- modsmith-0.1.0/docs/assets/pixel/globe.svg +4 -0
- modsmith-0.1.0/docs/assets/pixel/heart.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/info.svg +1 -0
- modsmith-0.1.0/docs/assets/pixel/key.svg +1 -0
- modsmith-0.1.0/docs/assets/pixel/layers.svg +1 -0
- modsmith-0.1.0/docs/assets/pixel/link.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/list.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/package.svg +4 -0
- modsmith-0.1.0/docs/assets/pixel/play.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/puzzle.svg +4 -0
- modsmith-0.1.0/docs/assets/pixel/question.svg +1 -0
- modsmith-0.1.0/docs/assets/pixel/refresh.svg +1 -0
- modsmith-0.1.0/docs/assets/pixel/search.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/shield.svg +3 -0
- modsmith-0.1.0/docs/assets/pixel/wrench.svg +3 -0
- modsmith-0.1.0/docs/concepts/index.md +27 -0
- modsmith-0.1.0/docs/concepts/loaders.md +38 -0
- modsmith-0.1.0/docs/concepts/platforms.md +37 -0
- modsmith-0.1.0/docs/concepts/sync.md +61 -0
- modsmith-0.1.0/docs/conf.py +254 -0
- modsmith-0.1.0/docs/get-started/concepts.md +50 -0
- modsmith-0.1.0/docs/get-started/index.md +27 -0
- modsmith-0.1.0/docs/get-started/installation.md +37 -0
- modsmith-0.1.0/docs/get-started/quickstart.md +80 -0
- modsmith-0.1.0/docs/guides/curseforge.md +60 -0
- modsmith-0.1.0/docs/guides/errors.md +84 -0
- modsmith-0.1.0/docs/guides/extending.md +99 -0
- modsmith-0.1.0/docs/guides/index.md +62 -0
- modsmith-0.1.0/docs/guides/instances.md +74 -0
- modsmith-0.1.0/docs/guides/java.md +49 -0
- modsmith-0.1.0/docs/guides/launcher.md +61 -0
- modsmith-0.1.0/docs/guides/loaders.md +76 -0
- modsmith-0.1.0/docs/guides/modpacks.md +74 -0
- modsmith-0.1.0/docs/guides/platforms.md +103 -0
- modsmith-0.1.0/docs/guides/progress.md +72 -0
- modsmith-0.1.0/docs/help/changelog.md +2 -0
- modsmith-0.1.0/docs/help/compatibility.md +27 -0
- modsmith-0.1.0/docs/help/contributing.md +2 -0
- modsmith-0.1.0/docs/help/faq.md +53 -0
- modsmith-0.1.0/docs/help/index.md +37 -0
- modsmith-0.1.0/docs/help/troubleshooting.md +87 -0
- modsmith-0.1.0/docs/index.md +176 -0
- modsmith-0.1.0/docs/reference/errors.md +7 -0
- modsmith-0.1.0/docs/reference/index.md +62 -0
- modsmith-0.1.0/docs/reference/instances.md +19 -0
- modsmith-0.1.0/docs/reference/java.md +32 -0
- modsmith-0.1.0/docs/reference/launcher.md +29 -0
- modsmith-0.1.0/docs/reference/loaders.md +57 -0
- modsmith-0.1.0/docs/reference/minecraft.md +41 -0
- modsmith-0.1.0/docs/reference/net.md +29 -0
- modsmith-0.1.0/docs/reference/packs.md +54 -0
- modsmith-0.1.0/docs/reference/platforms.md +52 -0
- modsmith-0.1.0/docs/reference/progress.md +20 -0
- modsmith-0.1.0/modsmith/__init__.py +36 -0
- modsmith-0.1.0/modsmith/_support.py +81 -0
- modsmith-0.1.0/modsmith/errors.py +115 -0
- modsmith-0.1.0/modsmith/instances.py +524 -0
- modsmith-0.1.0/modsmith/java.py +294 -0
- modsmith-0.1.0/modsmith/launcher.py +256 -0
- modsmith-0.1.0/modsmith/loaders/__init__.py +23 -0
- modsmith-0.1.0/modsmith/loaders/_base.py +157 -0
- modsmith-0.1.0/modsmith/loaders/_fabric.py +166 -0
- modsmith-0.1.0/modsmith/loaders/_forge.py +312 -0
- modsmith-0.1.0/modsmith/loaders/_install_profile.py +359 -0
- modsmith-0.1.0/modsmith/loaders/_processors.py +223 -0
- modsmith-0.1.0/modsmith/minecraft/__init__.py +15 -0
- modsmith-0.1.0/modsmith/minecraft/_game_dir.py +168 -0
- modsmith-0.1.0/modsmith/minecraft/_maven.py +75 -0
- modsmith-0.1.0/modsmith/minecraft/_remote.py +115 -0
- modsmith-0.1.0/modsmith/net/__init__.py +7 -0
- modsmith-0.1.0/modsmith/net/_download.py +243 -0
- modsmith-0.1.0/modsmith/net/_resource.py +118 -0
- modsmith-0.1.0/modsmith/net/_session.py +241 -0
- modsmith-0.1.0/modsmith/packs/__init__.py +18 -0
- modsmith-0.1.0/modsmith/packs/_formats.py +262 -0
- modsmith-0.1.0/modsmith/packs/_model.py +247 -0
- modsmith-0.1.0/modsmith/platforms/__init__.py +25 -0
- modsmith-0.1.0/modsmith/platforms/_base.py +312 -0
- modsmith-0.1.0/modsmith/platforms/_curseforge.py +390 -0
- modsmith-0.1.0/modsmith/platforms/_modrinth.py +261 -0
- modsmith-0.1.0/modsmith/progress.py +78 -0
- modsmith-0.1.0/modsmith/py.typed +0 -0
- modsmith-0.1.0/pyproject.toml +131 -0
- modsmith-0.1.0/tests/__init__.py +0 -0
- modsmith-0.1.0/tests/conftest.py +55 -0
- modsmith-0.1.0/tests/data/install_profiles/forge-1.13.2.json +429 -0
- modsmith-0.1.0/tests/data/install_profiles/forge-1.16.5.json +603 -0
- modsmith-0.1.0/tests/data/install_profiles/forge-1.20.1.json +728 -0
- modsmith-0.1.0/tests/data/install_profiles/forge-1.21.1.json +501 -0
- modsmith-0.1.0/tests/data/install_profiles/neoforge-1.20.1.json +827 -0
- modsmith-0.1.0/tests/data/install_profiles/neoforge-21.1.json +1140 -0
- modsmith-0.1.0/tests/data/processor/Helper.java +9 -0
- modsmith-0.1.0/tests/data/processor/Tool.java +54 -0
- modsmith-0.1.0/tests/functional/test_docs.py +47 -0
- modsmith-0.1.0/tests/functional/test_download.py +274 -0
- modsmith-0.1.0/tests/functional/test_instances.py +452 -0
- modsmith-0.1.0/tests/functional/test_java.py +120 -0
- modsmith-0.1.0/tests/functional/test_loaders.py +376 -0
- modsmith-0.1.0/tests/functional/test_minecraft.py +69 -0
- modsmith-0.1.0/tests/functional/test_processors.py +157 -0
- modsmith-0.1.0/tests/functional/test_session.py +91 -0
- modsmith-0.1.0/tests/lib/__init__.py +0 -0
- modsmith-0.1.0/tests/lib/builders.py +119 -0
- modsmith-0.1.0/tests/lib/docs.py +42 -0
- modsmith-0.1.0/tests/lib/server.py +117 -0
- modsmith-0.1.0/tests/live/test_curseforge.py +139 -0
- modsmith-0.1.0/tests/live/test_docs.py +28 -0
- modsmith-0.1.0/tests/live/test_game_files.py +64 -0
- modsmith-0.1.0/tests/live/test_modrinth.py +100 -0
- modsmith-0.1.0/tests/unit/test_game_dir.py +70 -0
- modsmith-0.1.0/tests/unit/test_install_profile.py +79 -0
- modsmith-0.1.0/tests/unit/test_launcher.py +127 -0
- modsmith-0.1.0/tests/unit/test_loader_registry.py +77 -0
- modsmith-0.1.0/tests/unit/test_maven.py +28 -0
- modsmith-0.1.0/tests/unit/test_packs.py +187 -0
- modsmith-0.1.0/tests/unit/test_public_api.py +46 -0
- modsmith-0.1.0/tests/unit/test_support.py +61 -0
- modsmith-0.1.0/uv.lock +1090 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
end_of_line = lf
|
|
6
|
+
indent_style = space
|
|
7
|
+
indent_size = 4
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
|
|
11
|
+
[*.{json,toml,yaml,yml}]
|
|
12
|
+
indent_size = 2
|
|
13
|
+
|
|
14
|
+
[*.md]
|
|
15
|
+
trim_trailing_whitespace = false
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Something does not work as documented
|
|
4
|
+
labels: bug
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**What happened?**
|
|
8
|
+
|
|
9
|
+
**What did you expect?**
|
|
10
|
+
|
|
11
|
+
**Code to reproduce it**
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Environment**
|
|
18
|
+
|
|
19
|
+
- Modsmith version:
|
|
20
|
+
- Python version:
|
|
21
|
+
- Operating system:
|
|
22
|
+
- Launcher (standalone or Microsoft Store):
|
|
23
|
+
- Minecraft version and mod loader:
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
|
|
3
|
+
updates:
|
|
4
|
+
- package-ecosystem: github-actions
|
|
5
|
+
directory: /
|
|
6
|
+
schedule:
|
|
7
|
+
interval: weekly
|
|
8
|
+
groups:
|
|
9
|
+
actions:
|
|
10
|
+
patterns: ["*"]
|
|
11
|
+
|
|
12
|
+
- package-ecosystem: uv
|
|
13
|
+
directory: /
|
|
14
|
+
schedule:
|
|
15
|
+
interval: weekly
|
|
16
|
+
groups:
|
|
17
|
+
dependencies:
|
|
18
|
+
patterns: ["*"]
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
workflow_call:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
concurrency:
|
|
14
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
15
|
+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
lint:
|
|
19
|
+
name: Lint and type check
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
timeout-minutes: 10
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
24
|
+
with:
|
|
25
|
+
persist-credentials: false
|
|
26
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
27
|
+
- name: Check the lockfile
|
|
28
|
+
run: uv lock --check
|
|
29
|
+
- run: uv sync --locked
|
|
30
|
+
- name: Run pre-commit hooks
|
|
31
|
+
run: uv run --no-sync pre-commit run --all-files --show-diff-on-failure
|
|
32
|
+
- name: Type check
|
|
33
|
+
run: uv run --no-sync pyright
|
|
34
|
+
|
|
35
|
+
test:
|
|
36
|
+
name: Test (${{ matrix.os }}, Python ${{ matrix.python }})
|
|
37
|
+
runs-on: ${{ matrix.os }}
|
|
38
|
+
timeout-minutes: 20
|
|
39
|
+
strategy:
|
|
40
|
+
fail-fast: false
|
|
41
|
+
matrix:
|
|
42
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
43
|
+
python: ["3.12", "3.13", "3.14"]
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
46
|
+
with:
|
|
47
|
+
persist-credentials: false
|
|
48
|
+
- uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
|
|
49
|
+
with:
|
|
50
|
+
distribution: temurin
|
|
51
|
+
java-version: "21"
|
|
52
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
53
|
+
with:
|
|
54
|
+
python-version: ${{ matrix.python }}
|
|
55
|
+
- run: uv sync --locked --no-default-groups --group test
|
|
56
|
+
- name: Run tests
|
|
57
|
+
run: uv run --no-sync pytest --cov
|
|
58
|
+
- name: Summarize coverage
|
|
59
|
+
shell: bash
|
|
60
|
+
run: uv run --no-sync coverage report --format=markdown >> "$GITHUB_STEP_SUMMARY"
|
|
61
|
+
|
|
62
|
+
minimum-dependencies:
|
|
63
|
+
name: Test (lowest dependencies)
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
timeout-minutes: 20
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
68
|
+
with:
|
|
69
|
+
persist-credentials: false
|
|
70
|
+
- uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad # v6.1.0
|
|
71
|
+
with:
|
|
72
|
+
distribution: temurin
|
|
73
|
+
java-version: "21"
|
|
74
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
75
|
+
- name: Run tests
|
|
76
|
+
run: uv run --isolated --resolution lowest-direct --group test pytest
|
|
77
|
+
|
|
78
|
+
docs:
|
|
79
|
+
name: Build documentation
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
timeout-minutes: 10
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
84
|
+
with:
|
|
85
|
+
persist-credentials: false
|
|
86
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
87
|
+
- run: uv sync --locked --no-default-groups --group docs
|
|
88
|
+
- name: Build the site
|
|
89
|
+
run: uv run --no-sync sphinx-build -W -n -b dirhtml docs docs/_build/html
|
|
90
|
+
- name: Run the examples
|
|
91
|
+
run: uv run --no-sync sphinx-build -W -b doctest docs docs/_build/doctest
|
|
92
|
+
|
|
93
|
+
build:
|
|
94
|
+
name: Build distributions
|
|
95
|
+
runs-on: ubuntu-latest
|
|
96
|
+
timeout-minutes: 10
|
|
97
|
+
steps:
|
|
98
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
99
|
+
with:
|
|
100
|
+
persist-credentials: false
|
|
101
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
102
|
+
- run: uv build
|
|
103
|
+
- name: Check package metadata
|
|
104
|
+
run: uvx twine check --strict dist/*
|
|
105
|
+
- name: Import the built wheel
|
|
106
|
+
run: uv run --isolated --no-project --with dist/*.whl python -c "import modsmith; print(modsmith.__version__)"
|
|
107
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
108
|
+
with:
|
|
109
|
+
name: dist
|
|
110
|
+
path: dist/
|
|
111
|
+
if-no-files-found: error
|
|
112
|
+
|
|
113
|
+
all-checks:
|
|
114
|
+
name: All checks
|
|
115
|
+
if: always()
|
|
116
|
+
needs: [lint, test, minimum-dependencies, docs, build]
|
|
117
|
+
runs-on: ubuntu-latest
|
|
118
|
+
timeout-minutes: 5
|
|
119
|
+
steps:
|
|
120
|
+
- name: Require every job to pass
|
|
121
|
+
env:
|
|
122
|
+
PASSED: ${{ !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') && !contains(needs.*.result, 'skipped') }}
|
|
123
|
+
run: test "$PASSED" = "true"
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: pages
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build:
|
|
17
|
+
name: Build the site
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
timeout-minutes: 10
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
25
|
+
- run: uv sync --locked --no-default-groups --group docs
|
|
26
|
+
- name: Build the site
|
|
27
|
+
run: uv run --no-sync sphinx-build -W -n -b dirhtml docs docs/_build/html
|
|
28
|
+
- uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
|
|
29
|
+
with:
|
|
30
|
+
path: docs/_build/html
|
|
31
|
+
|
|
32
|
+
deploy:
|
|
33
|
+
name: Deploy to GitHub Pages
|
|
34
|
+
needs: build
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
timeout-minutes: 10
|
|
37
|
+
permissions:
|
|
38
|
+
pages: write
|
|
39
|
+
id-token: write
|
|
40
|
+
environment:
|
|
41
|
+
name: github-pages
|
|
42
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
43
|
+
steps:
|
|
44
|
+
- id: deployment
|
|
45
|
+
uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Live tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
schedule:
|
|
5
|
+
- cron: "17 3 * * 1"
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
concurrency:
|
|
12
|
+
group: ${{ github.workflow }}
|
|
13
|
+
cancel-in-progress: false
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
live:
|
|
17
|
+
name: Live (${{ matrix.os }})
|
|
18
|
+
runs-on: ${{ matrix.os }}
|
|
19
|
+
timeout-minutes: 60
|
|
20
|
+
strategy:
|
|
21
|
+
fail-fast: false
|
|
22
|
+
matrix:
|
|
23
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
26
|
+
with:
|
|
27
|
+
persist-credentials: false
|
|
28
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
29
|
+
- run: uv sync --locked --no-default-groups --group test
|
|
30
|
+
- name: Run live tests
|
|
31
|
+
env:
|
|
32
|
+
CURSEFORGE_API_KEY: ${{ secrets.CURSEFORGE_API_KEY }}
|
|
33
|
+
run: uv run --no-sync pytest tests/live
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
check-version:
|
|
12
|
+
name: Check the tag
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 5
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
20
|
+
- name: Compare the tag with the project version
|
|
21
|
+
env:
|
|
22
|
+
TAG: ${{ github.ref_name }}
|
|
23
|
+
run: test "v$(uv version --short)" = "$TAG"
|
|
24
|
+
|
|
25
|
+
ci:
|
|
26
|
+
name: CI
|
|
27
|
+
needs: check-version
|
|
28
|
+
uses: ./.github/workflows/ci.yml
|
|
29
|
+
|
|
30
|
+
pypi:
|
|
31
|
+
name: Publish to PyPI
|
|
32
|
+
needs: ci
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
timeout-minutes: 10
|
|
35
|
+
environment:
|
|
36
|
+
name: pypi
|
|
37
|
+
url: https://pypi.org/project/modsmith/
|
|
38
|
+
permissions:
|
|
39
|
+
id-token: write
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
42
|
+
with:
|
|
43
|
+
name: dist
|
|
44
|
+
path: dist/
|
|
45
|
+
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
46
|
+
|
|
47
|
+
github-release:
|
|
48
|
+
name: Create the GitHub release
|
|
49
|
+
needs: pypi
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
timeout-minutes: 5
|
|
52
|
+
permissions:
|
|
53
|
+
contents: write
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
56
|
+
with:
|
|
57
|
+
name: dist
|
|
58
|
+
path: dist/
|
|
59
|
+
- name: Create the release
|
|
60
|
+
env:
|
|
61
|
+
GH_TOKEN: ${{ github.token }}
|
|
62
|
+
GH_REPO: ${{ github.repository }}
|
|
63
|
+
TAG: ${{ github.ref_name }}
|
|
64
|
+
run: gh release create "$TAG" dist/* --verify-tag --generate-notes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
wheels/
|
|
8
|
+
|
|
9
|
+
# Environments
|
|
10
|
+
.venv/
|
|
11
|
+
.env
|
|
12
|
+
|
|
13
|
+
# Tool caches
|
|
14
|
+
.cache/
|
|
15
|
+
.coverage
|
|
16
|
+
.coverage.*
|
|
17
|
+
.pyright/
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
htmlcov/
|
|
21
|
+
|
|
22
|
+
# Editors and systems
|
|
23
|
+
.idea/
|
|
24
|
+
.vscode/
|
|
25
|
+
.DS_Store
|
|
26
|
+
Thumbs.db
|
|
27
|
+
|
|
28
|
+
# Local game files and logs
|
|
29
|
+
*.log
|
|
30
|
+
.minecraft/
|
|
31
|
+
|
|
32
|
+
# Documentation
|
|
33
|
+
docs/_build/
|
|
34
|
+
docs/reference/*/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-merge-conflict
|
|
6
|
+
- id: check-toml
|
|
7
|
+
- id: check-yaml
|
|
8
|
+
- id: end-of-file-fixer
|
|
9
|
+
- id: trailing-whitespace
|
|
10
|
+
|
|
11
|
+
- repo: local
|
|
12
|
+
hooks:
|
|
13
|
+
- id: ruff-check
|
|
14
|
+
name: ruff check
|
|
15
|
+
entry: uv run --no-sync ruff check --fix --force-exclude
|
|
16
|
+
language: system
|
|
17
|
+
types_or: [python, pyi]
|
|
18
|
+
- id: ruff-format
|
|
19
|
+
name: ruff format
|
|
20
|
+
entry: uv run --no-sync ruff format --force-exclude
|
|
21
|
+
language: system
|
|
22
|
+
types_or: [python, pyi]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file. The format is
|
|
4
|
+
based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this
|
|
5
|
+
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-11-03
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `modsmith.platforms`: search and fetch from Modrinth and CurseForge.
|
|
14
|
+
- `modsmith.packs`: read mrpack and CurseForge modpacks without network access.
|
|
15
|
+
- `modsmith.loaders`: install Forge, NeoForge, Fabric and Quilt.
|
|
16
|
+
- `modsmith.instances`: `Instance.diff()` and `Instance.sync()` for installing
|
|
17
|
+
and updating game directories while keeping user changes.
|
|
18
|
+
- `modsmith.minecraft`, `modsmith.java`, `modsmith.launcher` and `modsmith.net`.
|
|
19
|
+
|
|
20
|
+
- `Instance.sync` stages new files and rolls back if it cannot finish, so a
|
|
21
|
+
failed update leaves the instance as it was.
|
|
22
|
+
- `Platform.iter_releases` reads releases page by page, so finding the latest
|
|
23
|
+
one takes a single request.
|
|
24
|
+
- Modpack overrides are streamed, so large packs no longer load into memory.
|
|
25
|
+
- `Instance` remembers file hashes, so a sync with nothing to do is faster.
|
|
26
|
+
- `Loader.is_installed` works offline for the built-in loaders.
|
|
27
|
+
- Download progress counts skipped and resumed files, and reaches the total.
|
|
28
|
+
- Forge and NeoForge installs prefer newer Java runtimes, which fixes old
|
|
29
|
+
versions on Windows and Apple Silicon.
|
|
30
|
+
- Requests respect `Retry-After`, and downloads use `If-Range` to resume.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- The project was renamed from CurseCraft and rebuilt as a developer toolkit.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Setup
|
|
4
|
+
|
|
5
|
+
You need [uv](https://docs.astral.sh/uv/) and a JDK, because the functional
|
|
6
|
+
tests compile and run a small processor jar.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv sync
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
uv run pre-commit install
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Checks
|
|
17
|
+
|
|
18
|
+
Run these before you open a pull request:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv run ruff format .
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uv run ruff check .
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
uv run pyright
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv run pytest --cov
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Testing
|
|
37
|
+
|
|
38
|
+
| Layer | Contains | Runs |
|
|
39
|
+
| :--- | :--- | :--- |
|
|
40
|
+
| `tests/unit` | Pure logic and real local files | By default |
|
|
41
|
+
| `tests/functional` | A real local HTTP server and a real JVM; the internet is blocked | By default |
|
|
42
|
+
| `tests/live` | Real platforms and complete loader installs | On request |
|
|
43
|
+
|
|
44
|
+
Run the live tests with:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv run pytest tests/live
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
CurseForge tests need `CURSEFORGE_API_KEY` and are skipped without it.
|
|
51
|
+
|
|
52
|
+
Tests do not use mocks. Do not use `unittest.mock`, patch internal functions or
|
|
53
|
+
fake a process or an HTTP client. Setting environment variables with
|
|
54
|
+
`monkeypatch` is allowed, because that configures the environment. If code is
|
|
55
|
+
hard to test this way, give it a parameter, such as a URL, instead.
|
|
56
|
+
|
|
57
|
+
Platform behaviour is tested only in `tests/live`, against the real services.
|
|
58
|
+
|
|
59
|
+
### Known gaps
|
|
60
|
+
|
|
61
|
+
- `replace_file` falls back to copying when a rename fails with `EXDEV`. The
|
|
62
|
+
cross-filesystem test only runs when the working directory and the temp
|
|
63
|
+
directory are on different drives. The MSIX behaviour that needed the
|
|
64
|
+
fallback cannot be reproduced in a normal environment.
|
|
65
|
+
- `is_running()` is checked against the real process table, but no test starts
|
|
66
|
+
the official launcher, and the Microsoft Store launcher's process name is
|
|
67
|
+
unconfirmed.
|
|
68
|
+
- No test starts the game.
|
|
69
|
+
|
|
70
|
+
## Docstrings
|
|
71
|
+
|
|
72
|
+
Write Google-style docstrings, in English, for every module, class and function.
|
|
73
|
+
Ruff checks that they exist, so also check that they match what the code does.
|
|
74
|
+
|
|
75
|
+
- Describe behaviour. Type annotations already give the types.
|
|
76
|
+
- Add `Args`, `Returns` and `Raises` when a caller needs them.
|
|
77
|
+
- Use single backticks for modsmith objects, which become links in the
|
|
78
|
+
documentation, and double backticks for parameters and literal values.
|
|
79
|
+
- Use a code comment only to explain why something is done.
|
|
80
|
+
|
|
81
|
+
## Documentation
|
|
82
|
+
|
|
83
|
+
The site is built with Sphinx and MyST, and the API reference comes from the
|
|
84
|
+
docstrings. Warnings and broken references fail the build:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
uv run sphinx-build -W -n -b dirhtml docs docs/_build/html
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Examples in docstrings run as tests:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
uv run sphinx-build -W -b doctest docs docs/_build/doctest
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Continuous integration
|
|
97
|
+
|
|
98
|
+
| Workflow | Runs | Does |
|
|
99
|
+
| :--- | :--- | :--- |
|
|
100
|
+
| `ci.yml` | Pull requests and pushes to `main` | Lint, type checks, tests on every OS and Python version, lowest dependencies, documentation, package build |
|
|
101
|
+
| `live.yml` | Every Monday, or by hand | Runs `tests/live` on every OS |
|
|
102
|
+
| `release.yml` | `v*` tags | Runs CI, publishes to PyPI and creates a GitHub release |
|
|
103
|
+
|
|
104
|
+
`ci.yml` ends with an `All checks` job, which is the one to require in branch
|
|
105
|
+
protection. `live.yml` reads `CURSEFORGE_API_KEY` from the repository secrets.
|
|
106
|
+
|
|
107
|
+
## Releasing
|
|
108
|
+
|
|
109
|
+
1. Set `version` in `pyproject.toml` and move the `Unreleased` notes in
|
|
110
|
+
`CHANGELOG.md` under the new version.
|
|
111
|
+
2. Merge that change into `main`.
|
|
112
|
+
3. Push a tag such as `v0.1.0`. The tag must match the project version.
|
|
113
|
+
|
|
114
|
+
## Commits
|
|
115
|
+
|
|
116
|
+
Keep the change focused, write the subject in the imperative mood, and add a
|
|
117
|
+
line to `CHANGELOG.md` under `Unreleased` when users will notice the change.
|
modsmith-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MeNeither
|
|
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.
|