diff --git a/RELEASE.md b/RELEASE.md
index 117d18b4..d4a7ed0a 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -7,7 +7,6 @@ Unless you're a core OnionShare developer making a release, you'll probably neve
### Update the version in these places
- [ ] `cli/pyproject.toml`
-- [ ] `cli/onionshare_cli/resources/version.txt`
- [ ] `desktop/pyproject.toml`
- [ ] `desktop/setup.py`
- [ ] `desktop/org.onionshare.OnionShare.appdata.xml`
@@ -118,7 +117,7 @@ In `flatpak/org.onionshare.OnionShare.yaml`:
# get onionshare dependencies
cd flatpak-build-tools/pip
- ./flatpak-pip-generator $(../../onionshare/flatpak/poetry-to-requirements.py ../../onionshare/desktop/pyproject.toml | grep -v PySide6)
+ ./flatpak-pip-generator $(../../onionshare/flatpak/pyproject-to-requirements.py ../../onionshare/desktop/pyproject.toml | grep -v PySide6)
../flatpak-json2yaml.py ./python3-modules.json
mv python3-modules.yml onionshare-desktop.yaml
```
@@ -285,7 +284,7 @@ Now, notarize the release. You will need an app-specific Apple ID password set u
```sh
export APPLE_PASSWORD="changeme" # This must be an app-specific Apple ID password, not your main Apple ID password
-export VERSION=$(cat ../cli/onionshare_cli/resources/version.txt)
+export VERSION=$(cat ../cli/pyproject.toml | python -c 'import tomllib,sys;print(tomllib.load(sys.stdin)["project"]["version"])')
# Notarize it
xcrun notarytool submit --apple-id "you@example.com" --team-id 7WLJ4UBL5L --password "$APPLE_PASSWORD" --progress --wait dist/OnionShare-$VERSION.dmg
diff --git a/cli/onionshare_cli/common.py b/cli/onionshare_cli/common.py
index 16f5b2fd..8cca4cf2 100644
--- a/cli/onionshare_cli/common.py
+++ b/cli/onionshare_cli/common.py
@@ -19,6 +19,7 @@ along with this program. If not, see .
"""
import base64
import hashlib
+import importlib.metadata as importlib_metadata
import importlib.resources as importlib_resources
import os
import platform
@@ -59,8 +60,7 @@ class Common:
self.platform = "BSD"
# The current version of OnionShare
- with open(self.get_resource_path("version.txt")) as f:
- self.version = f.read().strip()
+ self.version = importlib_metadata.version(__package__)
def display_banner(self):
"""
diff --git a/cli/onionshare_cli/resources/version.txt b/cli/onionshare_cli/resources/version.txt
deleted file mode 100644
index ec1cf33c..00000000
--- a/cli/onionshare_cli/resources/version.txt
+++ /dev/null
@@ -1 +0,0 @@
-2.6.3
diff --git a/cli/pyproject.toml b/cli/pyproject.toml
index 6ee7e64a..8371479f 100644
--- a/cli/pyproject.toml
+++ b/cli/pyproject.toml
@@ -1,9 +1,16 @@
-[tool.poetry]
+[project]
name = "onionshare_cli"
version = "2.6.3"
-description = "OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does _not_ require setting up a separate server or using a third party file-sharing service."
-authors = ["Micah Lee "]
-license = "GPLv3+"
+description = "Securely and anonymously share files, host websites, and chat with friends using the Tor network"
+requires-python = ">=3.10,<3.13"
+authors = [
+ { name = "Micah Lee", email = "micah@micahflee.com" },
+]
+maintainers = [
+ { name = "Micah Lee", email = "micah@micahflee.com" },
+]
+license = { text = "GPL-3.0-or-later" }
+keywords = [ "onion", "share", "onionshare", "tor", "anonymous", "web server" ]
classifiers = [
"Programming Language :: Python :: 3",
"Framework :: Flask",
@@ -14,39 +21,58 @@ classifiers = [
"Operating System :: OS Independent",
"Environment :: Web Environment",
]
+dependencies = [
+ "click",
+ "flask == 2.3.2",
+ "flask-compress >= 1.13, < 2.0",
+ "flask-socketio == 5.3.4",
+ "psutil",
+ "pysocks",
+ "requests[socks]",
+ "unidecode",
+ "urllib3 >= 2.2.2, < 3.0",
+ "eventlet",
+ "pynacl",
+ "colorama",
+ "gevent-websocket",
+ "stem == 1.8.1",
+ "waitress >= 3.0.1, < 4.0.0",
+ "werkzeug == 3.0.6",
+ "packaging >= 24",
+ "gevent >= 23.9.1, < 24.0.0",
+ "qrcode >= 7.4.2, < 8.0.0",
+]
-[tool.poetry.dependencies]
-python = ">=3.10,<3.13"
-click = "*"
-flask = "2.3.2"
-flask-compress = "^1.13"
-flask-socketio = "5.3.4"
-psutil = "*"
-pysocks = "*"
-requests = {extras = ["socks"], version = "*"}
-unidecode = "*"
-urllib3 = "^2.2.2"
-eventlet = "*"
-setuptools = ">=70.0.0"
-pynacl = "*"
-colorama = "*"
-gevent-websocket = "*"
-stem = "1.8.1"
-waitress = "^3.0.1"
-werkzeug = "3.0.6"
-packaging = ">=24"
-gevent = "^23.9.1"
-wheel = "^0.41.2"
-cffi = "^1.15.1"
-cython = "^3.0.2"
-qrcode = "^7.4.2"
+[project.urls]
+homepage = "https://onionshare.org"
+repository = "https://github.com/onionshare/onionshare"
+documentation = "https://docs.onionshare.org/"
+
+[project.scripts]
+onionshare-cli = "onionshare_cli:main"
+
+[tool.setuptools]
+packages = [
+ "onionshare_cli",
+ "onionshare_cli.web",
+]
+
+[tool.setuptools.package-data]
+onionshare_cli = [
+ "resources/*",
+ "resources/static/*",
+ "resources/static/css/*",
+ "resources/static/img/*",
+ "resources/static/js/*",
+ "resources/templates/*",
+]
[tool.poetry.group.dev.dependencies]
+setuptools = ">=70.0.0"
+
+[tool.poetry.group.test.dependencies]
pytest = ">=7.2.0"
-[tool.poetry.scripts]
-onionshare-cli = 'onionshare_cli:main'
-
[build-system]
-requires = ["poetry-core"]
+requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
diff --git a/cli/setup.py b/cli/setup.py
index d401afec..3ae0deaf 100644
--- a/cli/setup.py
+++ b/cli/setup.py
@@ -18,55 +18,6 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
"""
-import os
-import setuptools
+from setuptools import setup
-with open(os.path.join("onionshare_cli", "resources", "version.txt")) as f:
- version = f.read().strip()
-
-setuptools.setup(
- name="onionshare-cli",
- version=version,
- long_description=(
- "OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, "
- "making it accessible as a Tor onion service, and generating an unguessable web address so others can "
- "download files from you, or upload files to you. It does _not_ require setting up a separate server or "
- "using a third party file-sharing service."
- ),
- author="Micah Lee",
- author_email="micah@micahflee.com",
- maintainer="Micah Lee",
- maintainer_email="micah@micahflee.com",
- url="https://onionshare.org",
- license="GPLv3",
- keywords="onion, share, onionshare, tor, anonymous, web server",
- classifiers=[
- "Programming Language :: Python :: 3",
- "Framework :: Flask",
- "Topic :: Communications :: File Sharing",
- "Topic :: Security :: Cryptography",
- "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
- "Intended Audience :: End Users/Desktop",
- "Operating System :: OS Independent",
- "Environment :: Web Environment",
- ],
- packages=[
- "onionshare_cli",
- "onionshare_cli.web",
- ],
- package_data={
- "onionshare_cli": [
- "resources/*",
- "resources/static/*",
- "resources/static/css/*",
- "resources/static/img/*",
- "resources/static/js/*",
- "resources/templates/*",
- ]
- },
- entry_points={
- "console_scripts": [
- "onionshare-cli = onionshare_cli:main",
- ],
- },
-)
+setup()
diff --git a/desktop/pyproject.toml b/desktop/pyproject.toml
index 595c15af..878d2128 100644
--- a/desktop/pyproject.toml
+++ b/desktop/pyproject.toml
@@ -1,31 +1,78 @@
-[tool.poetry]
+[project]
name = "onionshare"
version = "2.6.3"
-description = "OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does _not_ require setting up a separate server or using a third party file-sharing service."
-authors = ["Micah Lee "]
-license = "GPLv3+"
+requires-python = ">=3.10,<3.13"
+description = "Securely and anonymously share files, host websites, and chat with friends using the Tor network"
+authors = [
+ { name = "Micah Lee", email = "micah@micahflee.com" },
+]
+maintainers = [
+ { name = "Micah Lee", email = "micah@micahflee.com" },
+]
+license = { text = "GPL-3.0-or-later" }
+keywords = [ "onion", "share", "onionshare", "tor", "anonymous", "web server" ]
+classifiers = [
+ "Programming Language :: Python :: 3",
+ "Framework :: Flask",
+ "Topic :: Communications :: File Sharing",
+ "Topic :: Security :: Cryptography",
+ "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
+ "Intended Audience :: End Users/Desktop",
+ "Operating System :: OS Independent",
+ "Environment :: Web Environment",
+]
+dependencies = [
+ "PySide6 == 6.8.2.1",
+ "qrcode",
+ "werkzeug == 3.0.6",
+ "python-gnupg",
+ "onionshare_cli",
+]
+
+[project.urls]
+homepage = "https://onionshare.org"
+repository = "https://github.com/onionshare/onionshare"
+documentation = "https://docs.onionshare.org/"
+
+[project.scripts]
+onionshare = 'onionshare:main'
+onionshare-cli = "onionshare_cli:main"
+
+[tool.setuptools]
+packages = [
+ "onionshare",
+ "onionshare.tab",
+ "onionshare.tab.mode",
+ "onionshare.tab.mode.share_mode",
+ "onionshare.tab.mode.receive_mode",
+ "onionshare.tab.mode.website_mode",
+ "onionshare.tab.mode.chat_mode",
+]
+
+[tool.setuptools.package-data]
+onionshare = [
+ "resources/*",
+ "resources/images/*",
+ "resources/images/countries/*",
+ "resources/locale/*",
+ "resources/countries/*",
+]
[tool.poetry.dependencies]
-python = ">=3.10,<3.13"
-onionshare_cli = {path = "../cli", develop = true}
-PySide6 = "6.8.2.1"
-qrcode = "*"
-werkzeug = "3.0.6"
-python-gnupg = "*"
+onionshare_cli = { path = "../cli", develop = true }
[tool.poetry.group.dev.dependencies]
click = "*"
black = "*"
+cx_freeze = "7.2.9"
+importlib-metadata = "*"
+tomli = { version = "^2.0.1", python = "<3.11" }
+
+[tool.poetry.group.test.dependencies]
pytest = "*"
pytest-faulthandler = "*"
pytest-qt = "*"
-cx_freeze = "7.2.9"
-importlib-metadata = "*"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
-
-[tool.poetry.scripts]
-onionshare = 'onionshare:main'
-onionshare-cli = 'onionshare_cli:main'
diff --git a/desktop/scripts/build-macos.py b/desktop/scripts/build-macos.py
index 7c709e08..3aa35b05 100644
--- a/desktop/scripts/build-macos.py
+++ b/desktop/scripts/build-macos.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
import os
+import sys
import inspect
import click
import platform
@@ -8,6 +9,11 @@ import shutil
import glob
import itertools
+if sys.version_info >= (3, 11):
+ import tomllib
+else:
+ import tomli as tomllib
+
from common import get_binary_arches
root = os.path.dirname(
@@ -270,9 +276,10 @@ def package(app_path):
return
print("> Create DMG")
- version_filename = f"{root}/cli/onionshare_cli/resources/version.txt"
- with open(version_filename) as f:
- version = f.read().strip()
+ pyproject_filename = f"{root}/cli/pyproject.toml"
+ with open(pyproject_filename, "rb") as f:
+ pyproject = tomllib.load(f)
+ version = pyproject['project']['version']
os.makedirs(f"{desktop_dir}/dist", exist_ok=True)
dmg_path = f"{desktop_dir}/dist/OnionShare-{version}.dmg"
diff --git a/desktop/scripts/build-windows.py b/desktop/scripts/build-windows.py
index 9b699918..7f263565 100644
--- a/desktop/scripts/build-windows.py
+++ b/desktop/scripts/build-windows.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
-from setuptools.command.build import build
-import sys
import os
+import sys
import inspect
import click
import shutil
@@ -10,6 +9,11 @@ import uuid
import xml.etree.ElementTree as ET
from glob import glob
+if sys.version_info >= (3, 11):
+ import tomllib
+else:
+ import tomli as tomllib
+
root = os.path.dirname(
os.path.dirname(
os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
@@ -165,17 +169,13 @@ def wix_build_components_xml(root, data):
return component_ids
-def msi_package(build_path, msi_path, product_update_code):
+def msi_package(build_path, msi_path, product_update_code, version):
print(f"> Build the WiX file")
- version_filename = os.path.join(
- build_path, "lib", "onionshare_cli", "resources", "version.txt"
- )
- with open(version_filename) as f:
- version = f.read().strip()
- # change a version like 2.6.dev1 to just 2.6, for cx_Freeze's sake
- last_digit = version[-1]
- if version.endswith(f".dev{last_digit}"):
- version = version[0:-5]
+
+ # change a version like 2.6.dev1 to just 2.6, for cx_Freeze's sake
+ last_digit = version[-1]
+ if version.endswith(f".dev{last_digit}"):
+ version = version[0:-5]
data = {
"id": "TARGETDIR",
@@ -428,16 +428,18 @@ def codesign(path):
@click.argument("path")
def package(path):
"""Build the MSI package"""
- version_filename = os.path.join(
- root, "cli", "onionshare_cli", "resources", "version.txt"
+ pyproject_filename = os.path.join(
+ root, "cli", "pyproject.toml"
)
- with open(version_filename) as f:
- version = f.read().strip()
+ with open(pyproject_filename, "rb") as f:
+ pyproject = tomllib.load(f)
+ version = pyproject['project']['version']
msi_package(
path,
os.path.join(desktop_dir, "dist", f"OnionShare-win64-{version}.msi"),
"ed7f9243-3528-4b4a-b85c-9943982e75eb",
+ version
)
diff --git a/desktop/setup-freeze.py b/desktop/setup-freeze.py
index 3f9059b5..e5702b6e 100644
--- a/desktop/setup-freeze.py
+++ b/desktop/setup-freeze.py
@@ -26,9 +26,16 @@ import cx_Freeze
from cx_Freeze import setup, Executable
from setuptools import find_packages
+if sys.version_info >= (3, 11):
+ import tomllib
+else:
+ import tomli as tomllib
+
# Discover the version
-with open(os.path.join("..", "cli", "onionshare_cli", "resources", "version.txt")) as f:
- version = f.read().strip()
+pyproject_filename = os.path.join("..", "cli", "pyproject.toml")
+with open(pyproject_filename, "rb") as f:
+ pyproject = tomllib.load(f)
+ version = pyproject['project']['version']
# change a version like 2.6.dev1 to just 2.6, for cx_Freeze's sake
last_digit = version[-1]
if version.endswith(f".dev{last_digit}"):
diff --git a/desktop/setup.py b/desktop/setup.py
index 825b000c..b896fdac 100644
--- a/desktop/setup.py
+++ b/desktop/setup.py
@@ -1,53 +1,11 @@
#!/usr/bin/env python3
# This file is used to build the Snapcraft and Flatpak packages
-import setuptools
+from setuptools import setup
# The version must be hard-coded because Snapcraft won't have access to ../cli
version = "2.6.3"
-setuptools.setup(
+setup(
name="onionshare",
version=version,
- long_description="Securely and anonymously share files, host websites, and chat with friends using the Tor network",
- author="Micah Lee",
- author_email="micah@micahflee.com",
- maintainer="Micah Lee",
- maintainer_email="micah@micahflee.com",
- url="https://onionshare.org",
- license="GPLv3",
- keywords="onion, share, onionshare, tor, anonymous, web server",
- classifiers=[
- "Programming Language :: Python :: 3",
- "Framework :: Flask",
- "Topic :: Communications :: File Sharing",
- "Topic :: Security :: Cryptography",
- "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
- "Intended Audience :: End Users/Desktop",
- "Operating System :: OS Independent",
- "Environment :: Web Environment",
- ],
- packages=[
- "onionshare",
- "onionshare.tab",
- "onionshare.tab.mode",
- "onionshare.tab.mode.share_mode",
- "onionshare.tab.mode.receive_mode",
- "onionshare.tab.mode.website_mode",
- "onionshare.tab.mode.chat_mode",
- ],
- package_data={
- "onionshare": [
- "resources/*",
- "resources/images/*",
- "resources/images/countries/*",
- "resources/locale/*",
- "resources/countries/*",
- ]
- },
- entry_points={
- "console_scripts": [
- "onionshare = onionshare:main",
- "onionshare-cli = onionshare_cli:main",
- ],
- },
)
diff --git a/docs/build.sh b/docs/build.sh
index 9019c60e..1c2b32d2 100755
--- a/docs/build.sh
+++ b/docs/build.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-VERSION=$(cat ../cli/onionshare_cli/resources/version.txt)
+VERSION=$(cat ../cli/pyproject.toml | python -c 'import tomllib,sys;print(tomllib.load(sys.stdin)["project"]["version"])')
# Supported locales
LOCALES="en sq bg zh_CN de el ga ja pl ru es tr uk"
diff --git a/flatpak/poetry-to-requirements.py b/flatpak/pyproject-to-requirements.py
old mode 100755
new mode 100644
similarity index 67%
rename from flatpak/poetry-to-requirements.py
rename to flatpak/pyproject-to-requirements.py
index 973e3c2e..b0afb3fc
--- a/flatpak/poetry-to-requirements.py
+++ b/flatpak/pyproject-to-requirements.py
@@ -1,7 +1,12 @@
#!/usr/bin/env python3
-import toml
+import sys
import click
+if sys.version_info >= (3, 11):
+ import tomllib
+else:
+ import tomli as tomllib
+
def format_version(dep, version):
if version == "*":
@@ -30,7 +35,7 @@ def format_version(dep, version):
def poetry_to_requirements(pyproject_filename):
"""Convert poetry dependencies in a pyproject.toml to requirements format."""
with open(pyproject_filename, "r") as f:
- data = toml.load(f)
+ data = tomllib.load(f)
dependencies = data.get("tool", {}).get("poetry", {}).get("dependencies", {})
@@ -48,5 +53,26 @@ def poetry_to_requirements(pyproject_filename):
print(req)
+@click.command()
+@click.argument("pyproject_filename")
+def pyproject_to_requirements(pyproject_filename):
+ """Convert PEP 631 dependencies in a pyproject.toml to requirements format."""
+ with open(pyproject_filename, "r") as f:
+ data = tomllib.load(f)
+
+ dependencies = data.get("project", {}).get("dependencies", [])
+
+ requirements = []
+
+ for dep in dependencies:
+ if dep == "onionshare_cli":
+ continue
+
+ requirements.append(dependencies)
+
+ for req in requirements:
+ print(req)
+
+
if __name__ == "__main__":
- poetry_to_requirements()
+ pyproject_to_requirements()