Spaces:
Running
Running
Commit
·
558414b
1
Parent(s):
8bbbb8b
Restructure project and use 'uv'
Browse files- .gitignore +151 -0
- .pre-commit-config.yaml +21 -0
- .python-version +1 -0
- LICENSE +25 -0
- compose.yaml +28 -0
- etc/branch-name-check.sh +9 -0
- etc/key_generator.py +12 -0
- etc/versioning.py +244 -0
- pyproject.toml +63 -0
- requirements.txt +0 -7
- uv.lock +0 -0
.gitignore
ADDED
@@ -0,0 +1,151 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
share/python-wheels/
|
24 |
+
*.egg-info/
|
25 |
+
.installed.cfg
|
26 |
+
*.egg
|
27 |
+
MANIFEST
|
28 |
+
|
29 |
+
# PyInstaller
|
30 |
+
# Usually these files are written by a python script from a template
|
31 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32 |
+
*.manifest
|
33 |
+
*.spec
|
34 |
+
|
35 |
+
# Installer logs
|
36 |
+
pip-log.txt
|
37 |
+
pip-delete-this-directory.txt
|
38 |
+
|
39 |
+
# Unit test / coverage reports
|
40 |
+
htmlcov/
|
41 |
+
.tox/
|
42 |
+
.nox/
|
43 |
+
.coverage
|
44 |
+
.coverage.*
|
45 |
+
.cache
|
46 |
+
nosetests.xml
|
47 |
+
coverage.xml
|
48 |
+
*.cover
|
49 |
+
*.py,cover
|
50 |
+
.hypothesis/
|
51 |
+
.pytest_cache/
|
52 |
+
cover/
|
53 |
+
|
54 |
+
# Translations
|
55 |
+
*.mo
|
56 |
+
*.pot
|
57 |
+
|
58 |
+
# Django stuff:
|
59 |
+
*.log
|
60 |
+
local_settings.py
|
61 |
+
db.sqlite3
|
62 |
+
db.sqlite3-journal
|
63 |
+
|
64 |
+
# Flask stuff:
|
65 |
+
instance/
|
66 |
+
.webassets-cache
|
67 |
+
|
68 |
+
# Scrapy stuff:
|
69 |
+
.scrapy
|
70 |
+
|
71 |
+
# Sphinx documentation
|
72 |
+
docs/_build/
|
73 |
+
|
74 |
+
# PyBuilder
|
75 |
+
.pybuilder/
|
76 |
+
target/
|
77 |
+
|
78 |
+
# Jupyter Notebook
|
79 |
+
.ipynb_checkpoints
|
80 |
+
|
81 |
+
# IPython
|
82 |
+
profile_default/
|
83 |
+
ipython_config.py
|
84 |
+
|
85 |
+
# pyenv
|
86 |
+
# For a library or package, you might want to ignore these files since the code is
|
87 |
+
# intended to run in multiple environments; otherwise, check them in:
|
88 |
+
# .python-version
|
89 |
+
|
90 |
+
# pipenv
|
91 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94 |
+
# install all needed dependencies.
|
95 |
+
# Pipfile.lock
|
96 |
+
|
97 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
98 |
+
__pypackages__/
|
99 |
+
|
100 |
+
# Celery stuff
|
101 |
+
celerybeat-schedule
|
102 |
+
celerybeat.pid
|
103 |
+
|
104 |
+
# SageMath parsed files
|
105 |
+
*.sage.py
|
106 |
+
|
107 |
+
# Environments
|
108 |
+
.venv
|
109 |
+
env/
|
110 |
+
venv/
|
111 |
+
ENV/
|
112 |
+
env.bak/
|
113 |
+
venv.bak/
|
114 |
+
.env
|
115 |
+
|
116 |
+
# Spyder project settings
|
117 |
+
.spyderproject
|
118 |
+
.spyproject
|
119 |
+
|
120 |
+
# Rope project settings
|
121 |
+
.ropeproject
|
122 |
+
|
123 |
+
# mkdocs documentation
|
124 |
+
/site
|
125 |
+
|
126 |
+
# mypy
|
127 |
+
.mypy_cache/
|
128 |
+
.dmypy.json
|
129 |
+
dmypy.json
|
130 |
+
|
131 |
+
# Ruff
|
132 |
+
.ruff_cache/
|
133 |
+
|
134 |
+
# Pyre type checker
|
135 |
+
.pyre/
|
136 |
+
|
137 |
+
# pytype static type analyzer
|
138 |
+
.pytype/
|
139 |
+
|
140 |
+
# IDE
|
141 |
+
.idea
|
142 |
+
|
143 |
+
# Cython debug symbols
|
144 |
+
cython_debug/
|
145 |
+
|
146 |
+
# Custom ignore files/folders
|
147 |
+
.DS_Store
|
148 |
+
.pypirc
|
149 |
+
.vscode
|
150 |
+
*credentials*.json
|
151 |
+
scratch*
|
.pre-commit-config.yaml
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
repos:
|
2 |
+
- repo: local
|
3 |
+
hooks:
|
4 |
+
- id: ruff-check
|
5 |
+
name: ruff-check
|
6 |
+
entry: ruff check --fix --force-exclude app etc
|
7 |
+
language: system
|
8 |
+
always_run: true
|
9 |
+
pass_filenames: false
|
10 |
+
- id: ruff-format
|
11 |
+
name: ruff-format
|
12 |
+
entry: ruff format --force-exclude app etc
|
13 |
+
language: system
|
14 |
+
always_run: true
|
15 |
+
pass_filenames: false
|
16 |
+
- id: branch-name-and-commit-permission-check
|
17 |
+
name: branch name and commit permission check
|
18 |
+
entry: bash ./etc/branch-name-check.sh
|
19 |
+
language: system
|
20 |
+
always_run: true
|
21 |
+
pass_filenames: false
|
.python-version
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
3.13
|
LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BSD 2-Clause License
|
2 |
+
|
3 |
+
Copyright (c) 2025, Saurabh Ghanekar
|
4 |
+
All rights reserved.
|
5 |
+
|
6 |
+
Redistribution and use in source and binary forms, with or without
|
7 |
+
modification, are permitted provided that the following conditions are met:
|
8 |
+
|
9 |
+
1. Redistributions of source code must retain the above copyright notice, this
|
10 |
+
list of conditions and the following disclaimer.
|
11 |
+
|
12 |
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
13 |
+
this list of conditions and the following disclaimer in the documentation
|
14 |
+
and/or other materials provided with the distribution.
|
15 |
+
|
16 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19 |
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
20 |
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24 |
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
compose.yaml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
services:
|
2 |
+
arcana-in-action:
|
3 |
+
build:
|
4 |
+
context: .
|
5 |
+
target: runtime
|
6 |
+
ports:
|
7 |
+
- 8698:7860
|
8 |
+
networks:
|
9 |
+
- arcana-in-action-net
|
10 |
+
- arcana-gateway-net
|
11 |
+
volumes:
|
12 |
+
- ./app:/app
|
13 |
+
environment:
|
14 |
+
ARCANA_API_KEY: "${ARCANA_API_KEY}"
|
15 |
+
MONGO_URI: "${MONGO_URI}"
|
16 |
+
OPENBLAS_NUM_THREADS: "${OPENBLAS_NUM_THREADS:-4}"
|
17 |
+
healthcheck:
|
18 |
+
test: ["CMD", "curl", "-f", "http://arcana-in-action/health"]
|
19 |
+
interval: 60s
|
20 |
+
timeout: 5s
|
21 |
+
retries: 3
|
22 |
+
|
23 |
+
networks:
|
24 |
+
arcana-in-action-net:
|
25 |
+
name: arcana-in-action-network
|
26 |
+
arcana-gateway-net:
|
27 |
+
name: arcana-gateway-network
|
28 |
+
external: true
|
etc/branch-name-check.sh
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
2 |
+
|
3 |
+
if [[ $BRANCH =~ (master|main|develop) ]]; then
|
4 |
+
echo "You are on branch $BRANCH. Are you sure you want to commit to this branch?"
|
5 |
+
echo "If so, commit with -n to bypass this pre-commit hook."
|
6 |
+
exit 1
|
7 |
+
fi
|
8 |
+
|
9 |
+
exit 0
|
etc/key_generator.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import secrets
|
2 |
+
import string
|
3 |
+
|
4 |
+
|
5 |
+
def generate_key(length=64):
|
6 |
+
alphabet = string.ascii_letters + string.digits
|
7 |
+
key = "".join(secrets.choice(alphabet) for _ in range(length))
|
8 |
+
return key
|
9 |
+
|
10 |
+
|
11 |
+
key = generate_key()
|
12 |
+
print(key)
|
etc/versioning.py
ADDED
@@ -0,0 +1,244 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
import tomllib
|
3 |
+
from enum import StrEnum
|
4 |
+
from pathlib import Path
|
5 |
+
from typing import Any
|
6 |
+
|
7 |
+
import click
|
8 |
+
from rich.console import Console
|
9 |
+
from rich.panel import Panel
|
10 |
+
from rich.table import Table
|
11 |
+
from rich.traceback import install
|
12 |
+
|
13 |
+
install(extra_lines=0, max_frames=10)
|
14 |
+
|
15 |
+
|
16 |
+
class VersionLevel(StrEnum):
|
17 |
+
MAJOR = "major"
|
18 |
+
MINOR = "minor"
|
19 |
+
PATCH = "patch"
|
20 |
+
ALPHA = "alpha"
|
21 |
+
BETA = "beta"
|
22 |
+
RC = "rc"
|
23 |
+
DEV = "dev"
|
24 |
+
RELEASE = "release"
|
25 |
+
|
26 |
+
|
27 |
+
class SupportedBackend(StrEnum):
|
28 |
+
POETRY = "poetry"
|
29 |
+
UV = "uv"
|
30 |
+
|
31 |
+
|
32 |
+
def load_config():
|
33 |
+
pyproject_path = Path.cwd() / "pyproject.toml"
|
34 |
+
if pyproject_path.exists():
|
35 |
+
with open(pyproject_path, "rb") as f:
|
36 |
+
pyproject_data = tomllib.load(f)
|
37 |
+
config = pyproject_data.get("tool", {}).get("versioning", {}).get("files")
|
38 |
+
|
39 |
+
backend = (
|
40 |
+
pyproject_data.get("tool", {}).get("versioning", {}).get("backend")
|
41 |
+
)
|
42 |
+
if backend is None:
|
43 |
+
raise RuntimeError(
|
44 |
+
"`pyproject.toml` file doesn't contain `tool.versioning.backend` property."
|
45 |
+
)
|
46 |
+
match SupportedBackend(backend):
|
47 |
+
case SupportedBackend.POETRY:
|
48 |
+
version = (
|
49 |
+
pyproject_data.get("tool", {}).get("poetry", {}).get("version")
|
50 |
+
)
|
51 |
+
case SupportedBackend.UV:
|
52 |
+
version = pyproject_data.get("project", {}).get("version")
|
53 |
+
|
54 |
+
if version is None:
|
55 |
+
raise RuntimeError(
|
56 |
+
"`pyproject.toml` file doesn't contain `version` property."
|
57 |
+
)
|
58 |
+
|
59 |
+
return version, config
|
60 |
+
else:
|
61 |
+
raise RuntimeError("Unable to locate `pyproject.toml` file.")
|
62 |
+
|
63 |
+
|
64 |
+
def parse_version(version) -> dict[str, str | Any]:
|
65 |
+
VERSION_PATTERN = re.compile(
|
66 |
+
r"^"
|
67 |
+
r"(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)"
|
68 |
+
r"(?:(?P<pre_type>a|b|rc)(?P<pre_num>\d+))?"
|
69 |
+
r"(?:\.post(?P<post>\d+))?"
|
70 |
+
r"(?:\.dev(?P<dev>\d+))?"
|
71 |
+
r"$"
|
72 |
+
)
|
73 |
+
|
74 |
+
pattern_match = VERSION_PATTERN.match(version)
|
75 |
+
if pattern_match:
|
76 |
+
return pattern_match.groupdict()
|
77 |
+
else:
|
78 |
+
raise ValueError(
|
79 |
+
f"Invalid version format {version}. Expected format: MAJOR.MINOR.PATCH[preTYPE[preNUM][.dev]]"
|
80 |
+
)
|
81 |
+
|
82 |
+
|
83 |
+
def find_substring_index(strings: list[str], substring: str) -> int:
|
84 |
+
return next(i for i, string in enumerate(strings) if substring in string)
|
85 |
+
|
86 |
+
|
87 |
+
def find_variable_and_replace_value_in_file(
|
88 |
+
file_name: str,
|
89 |
+
variable_name: str,
|
90 |
+
new_value: str,
|
91 |
+
dry_run: bool,
|
92 |
+
return_changed_line_number: bool = False,
|
93 |
+
) -> None | int:
|
94 |
+
file = Path.cwd() / file_name
|
95 |
+
text = file.read_text().splitlines(keepends=True)
|
96 |
+
line_index = find_substring_index(text, variable_name)
|
97 |
+
text[line_index] = text[line_index].replace(
|
98 |
+
re.search(f"{variable_name}.*$", text[line_index]).group(0),
|
99 |
+
variable_name + " = " + f'"{new_value}"',
|
100 |
+
)
|
101 |
+
|
102 |
+
if not dry_run:
|
103 |
+
file.write_text("".join(text))
|
104 |
+
|
105 |
+
if return_changed_line_number:
|
106 |
+
return line_index + 1
|
107 |
+
|
108 |
+
|
109 |
+
def sync_version_in_different_files(
|
110 |
+
version, config, dry_run: bool
|
111 |
+
) -> list[dict[str, int | str]]:
|
112 |
+
files_synced = []
|
113 |
+
if "version_variable" in config:
|
114 |
+
for value in config.get("version_variable"):
|
115 |
+
file_name = value.split(":")[0]
|
116 |
+
variable_name = value.split(":")[1]
|
117 |
+
|
118 |
+
line_number = find_variable_and_replace_value_in_file(
|
119 |
+
file_name,
|
120 |
+
variable_name,
|
121 |
+
version,
|
122 |
+
dry_run,
|
123 |
+
return_changed_line_number=True,
|
124 |
+
)
|
125 |
+
|
126 |
+
files_synced.append(
|
127 |
+
{
|
128 |
+
"file_path": file_name,
|
129 |
+
"line_number": line_number,
|
130 |
+
}
|
131 |
+
)
|
132 |
+
|
133 |
+
return files_synced
|
134 |
+
|
135 |
+
|
136 |
+
def versioning(level: VersionLevel, current_version: str, dry_run: bool) -> str:
|
137 |
+
version_parts = parse_version(current_version)
|
138 |
+
|
139 |
+
match level:
|
140 |
+
case VersionLevel.MAJOR:
|
141 |
+
new_version = f"{int(version_parts['major']) + 1}.0.0"
|
142 |
+
case VersionLevel.MINOR:
|
143 |
+
new_version = (
|
144 |
+
f"{version_parts['major']}.{int(version_parts['minor']) + 1}.0"
|
145 |
+
)
|
146 |
+
case VersionLevel.PATCH:
|
147 |
+
new_version = f"{version_parts['major']}.{version_parts['minor']}.{int(version_parts['patch']) + 1}"
|
148 |
+
case VersionLevel.ALPHA | VersionLevel.BETA | VersionLevel.RC:
|
149 |
+
pre_type_map = {
|
150 |
+
VersionLevel.ALPHA: "a",
|
151 |
+
VersionLevel.BETA: "b",
|
152 |
+
VersionLevel.RC: "rc",
|
153 |
+
}
|
154 |
+
|
155 |
+
if version_parts["pre_type"] == pre_type_map[level]:
|
156 |
+
pre_num = int(version_parts["pre_num"] or 0) + 1
|
157 |
+
else:
|
158 |
+
pre_num = 1
|
159 |
+
|
160 |
+
new_version = f"{version_parts['major']}.{version_parts['minor']}.{version_parts['patch']}{pre_type_map[level]}{pre_num}"
|
161 |
+
case VersionLevel.DEV:
|
162 |
+
if version_parts["pre_type"] and version_parts["pre_num"]:
|
163 |
+
pre_parts = f"{version_parts['pre_type']}{version_parts['pre_num']}"
|
164 |
+
else:
|
165 |
+
pre_parts = ""
|
166 |
+
|
167 |
+
dev_num = int(version_parts["dev"] or 0) + 1
|
168 |
+
new_version = f"{version_parts['major']}.{version_parts['minor']}.{version_parts['patch']}{pre_parts}.dev{dev_num}"
|
169 |
+
case VersionLevel.RELEASE:
|
170 |
+
if (
|
171 |
+
version_parts["pre_type"]
|
172 |
+
or version_parts["pre_num"]
|
173 |
+
or version_parts["dev"]
|
174 |
+
):
|
175 |
+
new_version = f"{version_parts['major']}.{version_parts['minor']}.{version_parts['patch']}"
|
176 |
+
else:
|
177 |
+
raise ValueError(
|
178 |
+
f"The project is already on release version {current_version}"
|
179 |
+
)
|
180 |
+
|
181 |
+
if not dry_run:
|
182 |
+
find_variable_and_replace_value_in_file(
|
183 |
+
"pyproject.toml", "version", new_version, dry_run=False
|
184 |
+
)
|
185 |
+
|
186 |
+
return new_version
|
187 |
+
|
188 |
+
|
189 |
+
def display_update_summary(
|
190 |
+
console: Console, files_synced: list[dict[str, int | str]]
|
191 |
+
) -> None:
|
192 |
+
grid = Table.grid()
|
193 |
+
grid.add_column(justify="center")
|
194 |
+
|
195 |
+
for sync_infomation in files_synced:
|
196 |
+
grid.add_row(
|
197 |
+
f"Synced version updates in file [cyan]`{sync_infomation['file_path']}`[/cyan] at line [cyan]{sync_infomation['line_number']}[/cyan]"
|
198 |
+
)
|
199 |
+
|
200 |
+
console.print(
|
201 |
+
Panel(grid, title="Version Update Summary", border_style="blue", padding=(1, 2))
|
202 |
+
)
|
203 |
+
|
204 |
+
|
205 |
+
@click.command()
|
206 |
+
@click.argument(
|
207 |
+
"level", type=click.Choice([vl.value for vl in VersionLevel], case_sensitive=False)
|
208 |
+
)
|
209 |
+
@click.option(
|
210 |
+
"--show-summary",
|
211 |
+
"-s",
|
212 |
+
is_flag=True,
|
213 |
+
help="Show what files changed",
|
214 |
+
)
|
215 |
+
@click.option(
|
216 |
+
"--dry-run",
|
217 |
+
"-d",
|
218 |
+
is_flag=True,
|
219 |
+
help="Show what would be done without making changes",
|
220 |
+
)
|
221 |
+
def main(level: str, show_summary: bool, dry_run: bool):
|
222 |
+
console = Console()
|
223 |
+
|
224 |
+
current_version, versioning_config = load_config()
|
225 |
+
new_version = versioning(VersionLevel(level), current_version, dry_run)
|
226 |
+
files_synced = sync_version_in_different_files(
|
227 |
+
new_version, versioning_config, dry_run
|
228 |
+
)
|
229 |
+
|
230 |
+
if dry_run:
|
231 |
+
console.print(
|
232 |
+
f"[yellow]Dry Run[/yellow]: Bumped version: [bold cyan]{current_version}[/bold cyan] :arrow_right: [bold green]{new_version}[/bold green]"
|
233 |
+
)
|
234 |
+
else:
|
235 |
+
console.print(
|
236 |
+
f"Bumped version: [bold cyan]{current_version}[/bold cyan] :arrow_right: [bold green]{new_version}[/bold green]"
|
237 |
+
)
|
238 |
+
|
239 |
+
if show_summary:
|
240 |
+
display_update_summary(console, files_synced)
|
241 |
+
|
242 |
+
|
243 |
+
if __name__ == "__main__":
|
244 |
+
main()
|
pyproject.toml
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[project]
|
2 |
+
name = "arcana-in-action"
|
3 |
+
version = "0.0.0"
|
4 |
+
description = "Huggingface Demo showcasing how Arcana works"
|
5 |
+
authors = [{ name = "Saurabh Ghanekar", email = "[email protected]" }]
|
6 |
+
license = "BSD-2-Clause"
|
7 |
+
license-files = ["LICENSE"]
|
8 |
+
readme = "README.md"
|
9 |
+
requires-python = ">=3.11"
|
10 |
+
dependencies = [
|
11 |
+
"fastapi-slim>=0.115",
|
12 |
+
"uvicorn>=0.34",
|
13 |
+
"pydantic>=2.10",
|
14 |
+
"pillow>=11.1",
|
15 |
+
"arcana-codex>=0.2",
|
16 |
+
"llama-cpp-python>=0.3",
|
17 |
+
"huggingface-hub>=0.29",
|
18 |
+
"pymongo>=4.11",
|
19 |
+
"email-validator>=2.2",
|
20 |
+
]
|
21 |
+
|
22 |
+
|
23 |
+
[dependency-groups]
|
24 |
+
dev = ["click>=8.1", "pre-commit>=4.0", "rich>=13.9", "ruff>=0.9"]
|
25 |
+
test = ["pytest>=8.3", "pytest-cov>=6.0"]
|
26 |
+
|
27 |
+
|
28 |
+
[tool.uv]
|
29 |
+
default-groups = ["dev", "test"]
|
30 |
+
|
31 |
+
|
32 |
+
[tool.ruff]
|
33 |
+
line-length = 88
|
34 |
+
|
35 |
+
|
36 |
+
[tool.ruff.lint]
|
37 |
+
select = [
|
38 |
+
# "D", # pydocstyle
|
39 |
+
"E", # pycodestyle errors
|
40 |
+
"W", # pycodestyle warnings
|
41 |
+
"F", # pyflakes
|
42 |
+
"I", # isort
|
43 |
+
"B", # flake8-bugbear
|
44 |
+
"C4", # flake8-comprehensions
|
45 |
+
"UP", # pyupgrade
|
46 |
+
"ARG001", # unused arguments in functions
|
47 |
+
]
|
48 |
+
ignore = [
|
49 |
+
"E501", # line too long, handled by black
|
50 |
+
"B008", # do not perform function calls in argument defaults
|
51 |
+
"W191", # indentation contains tabs
|
52 |
+
"B904", # Allow raising exceptions without from e, for HTTPException
|
53 |
+
]
|
54 |
+
|
55 |
+
|
56 |
+
[tool.ruff.lint.pydocstyle]
|
57 |
+
convention = "google"
|
58 |
+
|
59 |
+
[tool.versioning]
|
60 |
+
backend = "uv"
|
61 |
+
|
62 |
+
[tool.versioning.files]
|
63 |
+
version_variable = ["app/app/main.py:__version__"]
|
requirements.txt
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
fastapi-slim
|
2 |
-
uvicorn[standard]
|
3 |
-
arcana-codex
|
4 |
-
pydantic
|
5 |
-
pillow
|
6 |
-
llama-cpp-python
|
7 |
-
huggingface-hub
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uv.lock
ADDED
The diff for this file is too large to render.
See raw diff
|
|