Skip to content

Commit 898adf1

Browse files
authored
Add uv for package manager (#1071)
* Add uv for package management * Replace Makefile for Python script (Macos support) * Add uv to documentation. * Update github actions to use uv
1 parent 84a468a commit 898adf1

File tree

15 files changed

+1840
-161
lines changed

15 files changed

+1840
-161
lines changed

.github/workflows/general.yaml

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- name: Install uv
2222
uses: astral-sh/setup-uv@v5
2323
with:
24-
version: "0.6.14"
24+
version: "0.9.9"
2525
- name: Set up Python 3.13
2626
uses: actions/setup-python@v3
2727
with:
@@ -39,7 +39,7 @@ jobs:
3939
- name: Install uv
4040
uses: astral-sh/setup-uv@v5
4141
with:
42-
version: "0.6.14"
42+
version: "0.9.9"
4343
- name: Set up Python 3.13
4444
uses: actions/setup-python@v3
4545
with:
@@ -48,29 +48,30 @@ jobs:
4848
uses: tlambert03/setup-qt-libs@v1
4949
- name: Install python requirements
5050
run: |
51-
uv pip install -r requirements.txt
52-
uv pip install -r dev-requirements.txt
51+
uv sync
5352
- name: Check pep8
5453
run: |
55-
uvx ruff check
54+
uvx ruff check
5655
- name: Run tests
5756
run: |
58-
pytest
57+
uv run pytest
5958
macos-packaging:
6059
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
6160
needs: tests
6261
runs-on: macos-13
6362
steps:
64-
- name: Checkout repository
65-
uses: actions/checkout@v4
63+
- uses: actions/checkout@v4
64+
- name: Install uv
65+
uses: astral-sh/setup-uv@v5
66+
with:
67+
version: "0.9.9"
6668
- name: Set up Python 3.13
6769
uses: actions/setup-python@v3
6870
with:
6971
python-version: "3.13"
7072
- name: Install Dependencies
7173
run: |
72-
pip3 install -r requirements.txt
73-
pip3 install pyinstaller==6.11.1
74+
uv sync
7475
brew install create-dmg
7576
- name: Build and notarize the dmg file
7677
env:
@@ -94,8 +95,11 @@ jobs:
9495
needs: tests
9596
runs-on: ubuntu-22.04
9697
steps:
97-
- name: Checkout repository
98-
uses: actions/checkout@v4
98+
- uses: actions/checkout@v4
99+
- name: Install uv
100+
uses: astral-sh/setup-uv@v5
101+
with:
102+
version: "0.9.9"
99103
- name: Set up Python 3.13
100104
uses: actions/setup-python@v3
101105
with:
@@ -111,11 +115,9 @@ jobs:
111115
# Fix PyInstaller warnings of Qt Dependencies missing
112116
sudo apt-get install synaptic
113117
sudo apt-get install libxcb-icccm4 libxcb-image0-dev libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1 libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor0 libxcb-shape0-dev
114-
115118
- name: Install Dependencies
116119
run: |
117-
pip3 install -r requirements.txt
118-
pip3 install pyinstaller==6.11.1
120+
uv sync
119121
- name: Build the deb package
120122
run: |
121123
chmod +x create-deb.sh
@@ -132,24 +134,26 @@ jobs:
132134
needs: tests
133135
runs-on: windows-2022
134136
steps:
135-
- name: Checkout code
136-
uses: actions/checkout@v4
137+
- uses: actions/checkout@v4
138+
- name: Install uv
139+
uses: astral-sh/setup-uv@v5
140+
with:
141+
version: "0.9.9"
137142
- name: Set up Python 3.13
138143
uses: actions/setup-python@v3
139144
with:
140145
python-version: "3.13"
141146
- name: Install Dependencies
142147
run: |
143-
pip3 install -r requirements.txt
144-
pip3 install pyinstaller==6.11.1
148+
uv sync
145149
- name: Install NSIS
146150
run: choco install nsis
147151
- name: Build with PyInstaller
148-
run: python build.py
152+
run: uv run build.py build
149153
- name: Compile installer
150154
shell: bash # Force bash shell for VERSION command
151155
run: |
152-
VERSION=$(python -c "import ode; print(ode.__version__)")
156+
VERSION=$(uv run python -c "import ode; print(ode.__version__)")
153157
makensis -DAPP_VERSION="$VERSION" ./packaging/windows/installer.nsi
154158
- name: Upload artifact
155159
uses: actions/upload-artifact@v4
@@ -163,8 +167,11 @@ jobs:
163167
needs: tests
164168
runs-on: ubuntu-22.04
165169
steps:
166-
- name: Checkout repository
167-
uses: actions/checkout@v4
170+
- uses: actions/checkout@v4
171+
- name: Install uv
172+
uses: astral-sh/setup-uv@v5
173+
with:
174+
version: "0.9.9"
168175
- name: Set up Python 3.13
169176
uses: actions/setup-python@v3
170177
with:
@@ -178,12 +185,11 @@ jobs:
178185
sudo apt-get install libxcb-icccm4 libxcb-image0-dev libxcb-keysyms1 libxcb-render-util0 libxcb-xkb1 libxcb-xinerama0 libxkbcommon-x11-0
179186
- name: Install Dependencies
180187
run: |
181-
pip3 install -r requirements.txt
182-
pip3 install pyinstaller==6.11.1
188+
uv sync
183189
- name: Build the deb package
184190
run: |
185191
VERSION=$(python -c "import ode; print(ode.__version__)")
186-
python build.py --onefile --name "opendataeditor-$VERSION.AppImage"
192+
uv run build.py --onefile --name "opendataeditor-$VERSION.AppImage"
187193
- name: Archive build artifacts
188194
uses: actions/upload-artifact@v4
189195
with:

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.13

Makefile

Lines changed: 0 additions & 69 deletions
This file was deleted.

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,25 @@ The Open Data Editor (ODE) is a **no-code application** to **explore, validate a
1919

2020

2121
# Useful links
22-
23-
🔵 [Open Data Editor Concept Note](https://opendataeditor.okfn.org/ode-concept-note.pdf)
22+
🔵 [Development guide](https://opendataeditor.okfn.org/contributing/development/)
2423

2524
🔵 [Open Data Editor User Guide and Project Documentation](https://opendataeditor.okfn.org/)
2625

2726
🔵 [Frictionless Framework](https://framework.frictionlessdata.io/)
2827

2928
🔵 [Frictionless Data](https://frictionlessdata.io/)
3029

31-
🔵 [Contributing Guide](https://opendataeditor.okfn.org/contributing/development/)
30+
🔵 [Contributing Guidelines](https://opendataeditor.okfn.org/contributing/contribution-guidelines)
3231

33-
🔵 [Technical Architecture](https://opendataeditor.okfn.org/contributing/architecture/)
32+
🔵 [Open Data Editor Concept Note](https://opendataeditor.okfn.org/ode-concept-note.pdf)
3433

3534
🔵 For all contributions: [Code of conduct](https://frictionlessdata.io/code-of-conduct/)
3635

3736
# How to download the ODE
3837

39-
Go to the latest [RELEASE](https://github.com/okfn/opendataeditor/releases/latest)
38+
You can download the latest version from the [ODE website](https://okfn.org/en/projects/open-data-editor/)
39+
40+
For previous releases, you can download them from Github [RELEASE](https://github.com/okfn/opendataeditor/releases)
4041
* For **Windows**:Download the most recent **EXE** file.
4142
* For **MacOS**:Download the most recent **DMG** file.
4243
* For **Linux**:Download the most recent **AppImage** or **DEB** file.

build.py

Lines changed: 70 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,67 @@
1-
import PyInstaller.__main__
21
import os
32
import platform
3+
import PyInstaller.__main__
4+
import subprocess
45
import sys
56

7+
8+
def run(cmd: list[str], cwd: str = "."):
9+
"""Run a subprocess command."""
10+
subprocess.run(cmd, check=True, cwd=cwd)
11+
12+
13+
def docs():
14+
"""Build the documentation and run a local server."""
15+
run(["make", "html"], cwd="docs")
16+
run(["python", "-m", "http.server", "-d", "build/html"], cwd="docs")
17+
18+
19+
def update_translations():
20+
"""Generate/update .ts files from the source code."""
21+
run(["pyside6-lupdate", "-extensions", "py", "-recursive", "ode", "-ts", "ode/assets/translations/de.ts", "-target-language", "de_DE"])
22+
run(["pyside6-lupdate", "-extensions", "py", "-recursive", "ode", "-ts", "ode/assets/translations/es.ts", "-target-language", "es_ES"])
23+
run(["pyside6-lupdate", "-extensions", "py", "-recursive", "ode", "-ts", "ode/assets/translations/fr.ts", "-target-language", "fr_FR"])
24+
run(["pyside6-lupdate", "-extensions", "py", "-recursive", "ode", "-ts", "ode/assets/translations/pt.ts", "-target-language", "pt_PT"])
25+
run(["pyside6-lupdate", "-extensions", "py", "-recursive", "ode", "-ts", "ode/assets/translations/it.ts", "-target-language", "it_IT"])
26+
27+
28+
def compile_translations():
29+
"""Compile .ts to .qm files."""
30+
run(["pyside6-lrelease", "ode/assets/translations/de.ts", "-qm", "ode/assets/translations/de.qm"])
31+
run(["pyside6-lrelease", "ode/assets/translations/es.ts", "-qm", "ode/assets/translations/es.qm"])
32+
run(["pyside6-lrelease", "ode/assets/translations/fr.ts", "-qm", "ode/assets/translations/fr.qm"])
33+
run(["pyside6-lrelease", "ode/assets/translations/pt.ts", "-qm", "ode/assets/translations/pt.qm"])
34+
run(["pyside6-lrelease", "ode/assets/translations/it.ts", "-qm", "ode/assets/translations/it.qm"])
35+
36+
637
def build_application():
738
"""Build an executable file for the Application."""
839
system = platform.system()
40+
41+
# Linux Defaults
42+
icon_path = "packaging/linux/icon.svg"
43+
app_name = "opendataeditor"
44+
945
if system == "Darwin": # macOS
1046
icon_path = "packaging/macos/icon.icns"
1147
app_name = "OpenDataEditor"
1248
elif system == "Windows":
1349
icon_path = "packaging/windows/icon.ico"
1450
app_name = "opendataeditor"
15-
elif system == "Linux":
16-
icon_path = "packaging/linux/icon.svg"
17-
app_name = "opendataeditor"
1851

1952
print("Creating executable file for Open Data Editor")
2053

2154
params = [
2255
"ode/main.py",
2356
"--windowed", # Required for Windows install to not open a console.
24-
"--collect-all", "frictionless", # Frictionless depends on data files
25-
"--collect-all", "ode", # Collect all assets from Open Data Editor
26-
"--collect-all", "llama_cpp", # Collect all assets from llama_cpp
27-
"--collect-all", "numpy", # Collect all assets from numpy (llama_cpp dependency)
57+
"--collect-all",
58+
"frictionless", # Frictionless depends on data files
59+
"--collect-all",
60+
"ode", # Collect all assets from Open Data Editor
61+
"--collect-all",
62+
"llama_cpp", # Collect all assets from llama_cpp
63+
"--collect-all",
64+
"numpy", # Collect all assets from numpy (llama_cpp dependency)
2865
"--log-level",
2966
"WARN",
3067
"--name",
@@ -43,16 +80,36 @@ def build_application():
4380
# is installed which might not be the case for all of our users.
4481
params.extend(["--add-binary", "C:\\Windows\\system32\\vcomp140.dll:."])
4582

46-
cli_args = sys.argv[1:]
47-
if cli_args:
48-
params.extend(cli_args)
49-
5083
PyInstaller.__main__.run(params)
5184

5285
# Clean the spec file generated by PyInstaller
5386
if os.path.exists(f"{app_name}.spec"):
5487
os.remove(f"{app_name}.spec")
5588

5689

90+
def main():
91+
if len(sys.argv) < 2:
92+
print("Usage:")
93+
print(" python build.py update-translations")
94+
print(" python build.py compile-translations")
95+
print(" python build.py build")
96+
print(" python build.py docs")
97+
sys.exit(1)
98+
99+
command = sys.argv[1].lower()
100+
101+
if command == "update-translations":
102+
update_translations()
103+
elif command == "compile-translations":
104+
compile_translations()
105+
elif command == "build":
106+
build_application()
107+
elif command == "docs":
108+
docs()
109+
else:
110+
print(f"Unknown command: {command}")
111+
sys.exit(1)
112+
113+
57114
if __name__ == "__main__":
58-
build_application()
115+
main()

create-deb.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mkdir -p tmp/usr/share/icons/hicolor/scalable/apps
2222
# Build the project
2323
[ -e build ] && rm -r build
2424
[ -e dist ] && rm -r dist
25-
python build.py
25+
uv run build.py build
2626

2727
# Copy files
2828
cp -r dist/opendataeditor tmp/opt/opendataeditor
@@ -39,7 +39,7 @@ find tmp/usr/share -type f -exec chmod 644 -- {} +
3939
chmod +x tmp/opt/opendataeditor/opendataeditor
4040

4141
# Create the deb package
42-
VERSION=$(python -c "import ode; print(ode.__version__)")
42+
VERSION=$(uv run python -c "import ode; print(ode.__version__)")
4343
FILENAME=opendataeditor-linux-$VERSION.deb
4444
[ -e dist/$FILENAME ] && rm dist/$FILENAME
4545
fpm -C tmp -s dir -t deb -n "opendataeditor" -v $VERSION -p dist/$FILENAME

0 commit comments

Comments
 (0)